如上图:
启动容器后,会对scope为singleton并且非懒加载的bean进行实例化(getBean方法触发实例化
);
按照BeanDefinition定义信息配置信息,注入所有属性;
如果实现了BeanNameAware
接口,会调用接口的setBeanName
方法,传入该bean的唯一标识,以便获取该bean的唯一标识;
如果实现了BeanFactoryAware
接口,会调用该接口的setBeanFactory
方法,传入该bean的BeanFactory,以便获取bean的BeanFactory;
如果实现了ApplicationContextAware
接口,会调用该接口的setApplicationContext
方法,传入该bean的ApplicationContext,以便获取该Bean的ApplicationContext;
如果实现了BeanPostProcessor
接口,则会回调该接口的postProcessBeforeInitialization
方法;
如果实现了InitializingBean
接口,会调用该接口的afterPropertiesSet
方法;
如果配置了init-method
方法,则执行此方法;
如果实现了BeanPostProcessor
接口,则会回调该接口的postProcessAfterInitialization
方法;
这个时候,就可以正式使用该bean了,对于scope为singleton的bean,Spring的ioc容器中会缓存一份该bean的实例,而对于prototype的bean,每次调用都会new一个新的对象,该对象的生命周期交给调用方管理,不由Spring容器管理;
容器关闭的时候,如果bean实现了DisposableBean
接口,则会回调该接口的destroy
方法;
如果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
。
参考:2.9、基于注解的容器配置
@Autowired, @Inject, @Resource以及@Value注解是通过BeanPostProcessor实现的,所以你不可以在你自己的BeanPostProcessor或者BeanFactoryPostProcessor中使用这些注解,而应该通过XML或者@Bean注解来配置。
下面是一个bean生命周期的实例:
LifeCycleBean,使用以上生命周期中各个回调方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public class LifeCycleBean implements BeanNameAware , BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { @Override public void setBeanName (String name) { System.out.println("==== 1.BeanNameAware.setBeanName: " + name); } @Override public void setBeanFactory (BeanFactory beanFactory) throws BeansException { System.out.println("==== 2.BeanFactoryAware.setBeanFactory: " + beanFactory); } @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { System.out.println("==== 3.ApplicationContextAware.setApplicationContext: " + applicationContext); } @PostConstruct public void initBean () { System.out.println("==== 5.CommonAnnotationBeanPostProcessor.postConstruct" ); } @Override public void afterPropertiesSet () throws Exception { System.out.println("==== 6.InitializingBean.afterPropertiesSet" ); } public void initMethod () { System.out.println("==== 7.init-method" ); } @PreDestroy public void destroyBean () { System.out.println("==== 9.CommonAnnotationBeanPostProcessor.preDestroy" ); } @Override public void destroy () throws Exception { System.out.println("==== 10.DisposableBean.destroy" ); } public void destroyMethod () { System.out.println("==== 11.destroy-method" ); } }
自定义BeanPostProcessor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Service public class BeanPostService implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (bean instanceof LifeCycleBean) { System.out.println("==== 4.BeanPostProcessor.postProcessBeforeInitialization: " + beanName); } return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { if (bean instanceof LifeCycleBean) { System.out.println("==== 8.BeanPostProcessor.postProcessAfterInitialization: " + beanName); } return bean; } }
xml配置
1 2 3 4 5 6 7 <?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 >
输出结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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
References
Top 50 Spring Interview Questions You Must Prepare In 2019
Spring Context and Bean Lifecycle callbacks: practical examples of usage
[Spring 20面试题]([https://github.com/Homiss/Java-interview-questions/blob/master/框架/Spring 面试题.md ](https://github.com/Homiss/Java-interview-questions/blob/master/框架/Spring 面试题.md ))