2

我正在尝试通过将属性“jmx-enabled”设置为 true 来将我的数据源添加到 JMX。我有两个数据源,因此配置属性有些不同:

datasource:
  main:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://chico-testdb1.build.internal\CHICOTEST;selectMethod=cursor;applicationName=omc;sendStringParametersAsUnicode=false
    username: *
    password: *
    max-active: 150
    jmx-enabled: true

我查看了 DataSourceAutoConfiguration 类,它似乎只在配置使用“spring.datasource”前缀时才创建 MBean。所以我在这个例子之后模拟了我自己的配置:

    @Bean
    @ConditionalOnProperty(prefix = "datasource.main", name = "jmx-enabled", havingValue="true")
    public Object dataSourceMBean(@Qualifier("mainDataSource") DataSource dataSource) {
        if (dataSource instanceof DataSourceProxy) {
            try {
                return ((DataSourceProxy) dataSource).createPool().getJmxPool();
            }
            catch (SQLException ex) {
                logger.warn("Cannot expose DataSource to JMX (could not connect)");
            }
        }
        return null;
    }

条件运行良好,此方法正在返回 Jmx 连接池。但是,这个 bean 仍然没有在 MBeanServer 中注册,我在日志中没有看到任何异常。

我已经能够通过在服务器上显式注册 bean 来解决这个问题,但是我觉得应该有更好的方法?

    @Bean
    @ConditionalOnProperty(prefix = "datasource.main", name = "jmx-enabled", havingValue="true")
    public ConnectionPool getJmxPool(@Qualifier("mainDataSource") DataSource dataSource, MBeanServer mBeanServer) throws SQLException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException {
        if (dataSource instanceof DataSourceProxy) {
            ConnectionPool pool = ((DataSourceProxy)dataSource).createPool().getJmxPool();
            mBeanServer.registerMBean(pool, new ObjectName("com.build.jdbc:type="+ dataSource.getClass().getName()+",name=main"));
            return pool;
        }
        return null;
    }
4

1 回答 1

4

使用内部静态类并显式依赖 mbeanExporter 解决了使用 spring-boot 1.3.2.RELEASE 时的问题

@Configuration
@ConditionalOnProperty(prefix = "datasource.main", name = "jmx-enabled")
@ConditionalOnClass(DataSourceProxy.class)
@ConditionalOnMissingBean(name = "mainDataSourceMBean")
protected static class TomcatDataSourceJmxConfiguration {

    @Bean
    @DependsOn("mbeanExporter")
    public Object mainDataSourceMBean(@Qualifier("mainDataSource") DataSource dataSource) {
        if (dataSource instanceof DataSourceProxy) {
            try {
                return ((DataSourceProxy) dataSource).createPool().getJmxPool();
            } catch (SQLException ex) {
                logger.warn("Cannot expose DataSource to JMX (could not connect)");
            }
        }
        return null;
    }
}
于 2016-10-05T17:49:47.990 回答