SpringBoot:设置数据源 "jmx-enabled" 未注册数据源
SpringBoot : Setting DataSource "jmx-enabled" is not registering the Datasource
我试图通过将 属性 "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 class,它似乎只在配置使用 "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;
}
使用内部静态 class 并明确依赖 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;
}
}
我试图通过将 属性 "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 class,它似乎只在配置使用 "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;
}
使用内部静态 class 并明确依赖 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;
}
}