未能在关闭 Spring Boot 应用程序时注销数据源 JMX MBean

2022-09-02 12:51:33

我有一个简单的Spring Boot应用程序,使用org.apache.commons.dbcp2.BasicDataSource作为dataSource bean。

数据源通过 Spring boot 自动公开为 MBean。

豆子声明:

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setUrl(dbUrl);
    dataSource.setDriverClassName(jdbcDriver);
    dataSource.setUsername(dbUserName);
    dataSource.setPassword(dbPassword);
    return dataSource;
}

一切都很好。但是,我在关闭应用程序时看到错误。仅当运行可执行 jar 时,才会发生此错误。使用 Gradle Spring 插件(gradle bootRun)时,不会显示此内容。

javax.management.InstanceNotFoundException: org.apache.commons.dbcp2:name=dataSource,type=BasicDataSource
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.exclusiveUnregisterMBean(DefaultMBeanServerInterceptor.java:427)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.unregisterMBean(DefaultMBeanServerInterceptor.java:415)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.unregisterMBean(JmxMBeanServer.java:546)
    at org.apache.commons.dbcp2.BasicDataSource.close(BasicDataSource.java:1822)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:350)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:273)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:540)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:516)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:827)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:485)
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:921)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:895)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.doClose(EmbeddedWebApplicationContext.java:152)
    at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:809)

我想知道,1。这个bean是如何被暴露为JMX MBean的?2. 如何正确注销此 MBean?


答案 1

Spring正试图关闭BasicDataSource两次:

  1. 基本数据源在应用程序关闭时自动关闭
  2. Spring使用默认销毁方法来关闭数据源,但它已经关闭

为避免这种情况,请使用:

@Bean(destroyMethod = "")
public DataSource dataSource() 

在 Java 配置中


答案 2

我遇到了同样的问题。添加 MBean 服务器并注册数据源也无法修复它。

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jmx.html

我的结论是,DBCP2 的 BasicDataSource 在从 MBean 服务器注销自身时存在错误。

我通过切换到mchange的c3p0来修复我的:http://www.mchange.com/projects/c3p0/


推荐