Spring IOC_Bean的生命周期

Spring IOC_Bean的生命周期

如上图:

1、启动容器后,会对scope为singleton并且非懒加载的bean进行实例化(getBean方法触发实例化);
2、按照BeanDefinition定义信息配置信息,注入所有属性;
3、如果实现了BeanNameAware接口,会调用接口的setBeanName方法,传入该bean的唯一标识,以便获取该bean的唯一标识;
4、如果实现了BeanFactoryAware接口,会调用该接口的setBeanFactory方法,传入该bean的BeanFactory,以便获取bean的BeanFactory;
5、如果实现了ApplicationContextAware接口,会调用该接口的setApplicationContext方法,传入该bean的ApplicationContext,以便获取该Bean的ApplicationContext;
6、如果实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialization方法;
7、如果实现了InitializingBean接口,会调用该接口的afterPropertiesSet方法;
8、如果配置了init-method方法,则执行此方法;
9、如果实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization方法;
这个时候,就可以正式使用该bean了,对于scope为singleton的bean,Spring的ioc容器中会缓存一份该bean的实例,而对于prototype的bean,每次调用都会new一个新的对象,该对象的生命周期交给调用方管理,不由Spring容器管理;
10、容器关闭的时候,如果bean实现了DisposableBean接口,则会回调该接口的destroy方法;
11、如果bean配置了destroy-method方法,会执行此方法。

Spring Bean的生命周期中,主要包含三个阶段:初始化阶段,使用阶段,销毁阶段。其中初始化阶段和销毁阶段主要通过以下回调方式进行介入调整:3个Aware接口,两类BeanPostProcessor(自定义BeanPostProcessor和基于注解的CommonAnnotationBeanPostProcessor),InitializingBean,DisposableBean,以及两个基于xml配置的方法(init-method, destroy-method)。

注意:需要在xml文件中需要以下配置以便开启CommonAnnotationBeanPostProcessor支持:

<context:annotation-config/>

这个配置会自动注册以下的post-processor: AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, 还有前面提到的 RequiredAnnotationBeanPostProcessor。

@Autowired, @Inject, @Resource以及@Value注解是通过BeanPostProcessor实现的,所以你不可以在你自己的BeanPostProcessor或者BeanFactoryPostProcessor中使用这些注解,而应该通过XML或者@Bean注解来配置。

下面是一个bean生命周期的实例:

LifeCycleBean,使用以上生命周期中各个回调方法:

/**
 * Created by arthinking on 17/11/2019.
 */
public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

    
    public void setBeanName(String name) {
        System.out.println("==== 1.BeanNameAware.setBeanName: " + name);
    }

    
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("==== 2.BeanFactoryAware.setBeanFactory: " + beanFactory);
    }

    
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("==== 3.ApplicationContextAware.setApplicationContext: " + applicationContext);
    }

    // ==== 4.BeanPostProcessor.postProcessBeforeInitialization

    /**
     * 由CommonAnnotationBeanPostProcessor处理, 相当于xml中的init-method配置
     */
    
    public void initBean() {
        System.out.println("==== 5.CommonAnnotationBeanPostProcessor.postConstruct");
    }

    
    public void afterPropertiesSet() throws Exception {
        System.out.println("==== 6.InitializingBean.afterPropertiesSet");
    }
    @PostConstruct
    public void initMethod() {
        System.out.println("==== 7.init-method");
    }

    // ==== 8.BeanPostProcessor.postProcessAfterInitialization

    /**
     * 由CommonAnnotationBeanPostProcessor处理, 相当于xml中的destroy-method配置
     */
    
    public void destroyBean() {
        System.out.println("==== 9.CommonAnnotationBeanPostProcessor.preDestroy");
    }

    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("==== 10.DisposableBean.destroy");
    }

    public void destroyMethod() {
        System.out.println("==== 11.destroy-method");
    }

}

自定义BeanPostProcessor:

/**
 * Created by arthinking on 17/11/2019.
 */
@Service
public class BeanPostService implements BeanPostProcessor {

    
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof LifeCycleBean) {
            System.out.println("==== 4.BeanPostProcessor.postProcessBeforeInitialization: " + beanName);
        }
        return bean;
    }

    
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof LifeCycleBean) {
            System.out.println("==== 8.BeanPostProcessor.postProcessAfterInitialization: " + beanName);
        }
        return bean;
    }

}

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="lifeCycleBean" class="com.itzhai.spring.demo.beans.LifeCycleBean" init-method="initMethod" destroy-method="destroyMethod"/>
</beans>

输出结果如下:

2019-11-17 17:06:44.658  INFO 59661 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
==== 1.BeanNameAware.setBeanName: lifeCycleBean
==== 2.BeanFactoryAware.setBeanFactory: org.springframework.beans.factory.support.DefaultListableBeanFactory@76f4b65: ...
==== 3.ApplicationContextAware.setApplicationContext: org.springframework.web.context.support.GenericWebApplicationContext@e25951c, started on Sun Nov 17 17:06:42 CST 2019
==== 4.BeanPostProcessor.postProcessBeforeInitialization: lifeCycleBean
==== 5.CommonAnnotationBeanPostProcessor.postConstruct
==== 6.InitializingBean.afterPropertiesSet
==== 7.init-method
==== 8.BeanPostProcessor.postProcessAfterInitialization: lifeCycleBean
...
2019-11-17 17:06:49.385  INFO 59661 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
==== 9.CommonAnnotationBeanPostProcessor.preDestroy
==== 10.DisposableBean.destroy
==== 11.destroy-method

Process finished with exit code 0

 

上一篇:我想挑战下我的软肋,动手实现个Spring应用上下文!


下一篇:关于C语言的独立(freestanding)和托管(hosted)环境