如上图:
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