helloworlde/SpringBoot-DynamicDataSource

通过AOP构建多数据源时Filters的构建问题

Closed this issue · 8 comments

配置文件里是设置了stat,wall,log4j,是否每个DruidDataSource的Filters列表都根据Filter的配置信息构建?还是只有Primary DataSource构建了?

已经试过了,每个DruidDataSource的Filters列表都自动构建,但是在监控页面的数据源页面看不到数据源。

当有请求产生之后才会真正的创建连接,初始化数据源,请求之后在监控页面可以看到相关的数据,为什么没有在程序启动之后初始化数据源我暂时没有找到问题原因

如果不使用AbstractRoutingDataSource,使用多套DataSource,多套SessionFactory时druid的数据源界面是可以显示所有数据源的。
我的做法和你一样,但是数据源界面貌似只能显示单个数据源,现在还在调查中

另外,你的这种多数据源配置还是硬编码,我考虑的是在properties或者yml文件中指定数据源的列表,和各个数据源的连接配置,使用固定的DynamicDataSource构建方法构建不知道个数的数据源。这样代码改动能避免最小。
你的分支代码里貌似没有对StatViewServlet和WebStatFilter的构建,是否需要补充?

StatViewServlet和WebStatFilter 的配置:

image

看到了你的配置,不过Filter的设定生效貌似只能是在有ConfigurationProperties注解,使用DruidDataSourceBuilder构建DruidDataSource时才能生效,但是这样构建的DataSource数目是固定的,不能根据配置文件动态构建了,我考虑的还是动态构建

DruidDataSourceStatManager的addDataSource方法代码

public synchronized static ObjectName addDataSource(Object dataSource, String name) 
{
        final Map<Object, ObjectName> instances = getInstances();
        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
        synchronized (instances) {
            if (instances.size() == 0) {
                try {
                    ObjectName objectName = new ObjectName(MBEAN_NAME);
                    if (!mbeanServer.isRegistered(objectName)) {
                        mbeanServer.registerMBean(instance, objectName);
                    }
                } catch (JMException ex) {
                    LOG.error("register mbean error", ex);
                }

                DruidStatService.registerMBean();
            }
        }
        ObjectName objectName = null;
        if (name != null) {
            try {
                objectName = new ObjectName("com.alibaba.druid:type=DruidDataSource,id=" + name);
                mbeanServer.registerMBean(dataSource, objectName);
            } catch (Throwable ex) {
                LOG.error("register mbean error", ex);
                objectName = null;
            }
        }
        if (objectName == null) {
            try {
                int id = System.identityHashCode(dataSource);
                objectName = new ObjectName("com.alibaba.druid:type=DruidDataSource,id=" + id);
                mbeanServer.registerMBean(dataSource, objectName);
            } catch (Throwable ex) {
                LOG.error("register mbean error", ex);
                objectName = null;
            }
        }
        instances.put(dataSource, objectName);
        return objectName;
}

对于AbstractRoutingDataSource而言,每一次切换DataSource时,加入mbeanServer会用的是同一个objectName,如果这个objectName已经注册过就不再注册,这样导致只有第一次注册的DataSource可见,以后各次的DataSource都无法注册。

刚才发现是自己自定义的DataSource Annotation位置没有放对,放在Service接口方法上,没有放到Service实现类上,改正以后就出现数据源了。