使用@Bean注解,在不配置destroyMethod时,其默认值为:redis
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
public static final String INFER_METHOD = "(inferred)";
也就是在不配置destroyMethod时,spring会使用推断的销毁方法,这种推断的方法要求知足:spring
1. public的ui
2. 无参数this
3. 方法名为close或shutdownspa
若是当一个bean正好有上面的方法,那么就会在销毁时调用。好比redis.clients.jedis.BinaryJedis 及子类就知足要求,有一个shutdown方法。可是他的shutdown方法是向redis-server发送shutdown命令,并非销毁链接。所以在这个Bean销毁时,实际上是不但愿调用该shutdown方法的。code
若是想防止调用推断的销毁方法,须要给destroyMethod赋值为"":orm
@Bean(destroyMethod = "")
接下来让咱们看看推断的销毁方法是如何生效的。server
首先,在建立bean时(见org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法),会调用:blog
// Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); }
该方法会检查销毁的方法(requiresDestruction里),而且注册DisposableBeanAdapter,DisposableBeanAdapter会最终调用bean的destroyMethod。get
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
其余逻辑就显而易见了,源码就不贴了