bean的shutdown

使用@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));
            }
        }
    }

 

其餘邏輯就顯而易見了,源碼就不貼了

相關文章
相關標籤/搜索