• bean的shutdown


    使用@Bean注解,在不配置destroyMethod时,其默认值为:

    String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
    public static final String INFER_METHOD = "(inferred)";

    也就是在不配置destroyMethod时,spring会使用推断的销毁方法,这种推断的方法要求满足:

    1. public的

    2. 无参数

    3. 方法名为close或shutdown

    如果当一个bean正好有上面的方法,那么就会在销毁时调用。比如redis.clients.jedis.BinaryJedis 及子类就满足要求,有一个shutdown方法。但是他的shutdown方法是向redis-server发送shutdown命令,并不是销毁连接。因此在这个Bean销毁时,其实是不希望调用该shutdown方法的。

    如果想防止调用推断的销毁方法,需要给destroyMethod赋值为"":

    @Bean(destroyMethod = "")

    接下来让我们看看推断的销毁方法是如何生效的。

    首先,在创建bean时(见org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法),会调用:

            // Register bean as disposable.
            try {
                registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }

    该方法会检查销毁的方法(requiresDestruction里),并且注册DisposableBeanAdapter,DisposableBeanAdapter会最终调用bean的destroyMethod。

    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));
                }
            }
        }

    其他逻辑就显而易见了,源码就不贴了

  • 相关阅读:
    4-10
    4-9
    第三章例3-4
    第三章例3-3
    第三章例3-2
    第三章例3-1
    第二章例2-11
    第二章例2-10
    第二章例2-9
    第二章例2-8
  • 原文地址:https://www.cnblogs.com/drizzlewithwind/p/10944074.html
Copyright © 2020-2023  润新知