Spring生命周期主要分为以下4大阶段:实例化、属性赋值、初始化阶段、销毁阶段,下面我一一详解@mikechen
第一步:实例化阶段
对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
下面我们结合代码来直观的看下,在 doCreateBean() 方法中:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 1. 实例化Bean BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); }
这里的createBeanInstance就是实例化Bean的入口,这一步仅仅是简单的实例化,并未进行依赖注入。
第二步:Bean属性赋值
实例化对象被包装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息以及通过BeanWrapper提供的设置属性的接口完成依赖注入。
下面我们结合代码来直观的看下:
// AbstractAutowireCapableBeanFactory.java protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 1. 实例化Bean BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object exposedObject = bean; try { // 2. Bean属性赋值 populateBean(beanName, mbd, instanceWrapper);
依然在 doCreateBean() 方法中,上面我注释的第2个步骤Bean属性赋值:populateBean这个方法就是属性注入入口。
第三步:初始化阶段
初始化阶段主要是在返回Bean之前做一些处理,主要由initializeBean()方法实现。
依然在 doCreateBean() 方法中,下面我注释的第3个步骤就是初始化,如下所示:
// AbstractAutowireCapableBeanFactory.java protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 1. Bean实例化 BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object exposedObject = bean; try { // 2. Bean属性赋值 populateBean(beanName, mbd, instanceWrapper); // 3. 初始化Bean exposedObject = initializeBean(beanName, exposedObject, mbd); }
initializeBean初始化的过程会较多,所以我们进到 initializeBean() 方法里具体看下其过程。
如下所示:
1. BeanPostProcessor 前置处理 if(mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } 2. 若实现 InitializingBean 接口, 调用 afterPropertiesSet() 方法 3. 若配置自定义的 init - method方法, 则执行 try { invokeInitMethods(beanName, wrappedBean, mbd); } catch(Throwable ex) { throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } // 4. BeanPostProceesor 后置处理 if(mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;
主要包含以下几大流程:
1.BeanPostProcessor前置处理
当经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。
1. BeanPostProcessor 前置处理 if(mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }
postProcessBeforeInitialzation:这个函数会先于InitialzationBean执行,因此称为前置处理。
2.InitializingBean 与init-method自定义方法
当BeanPostProcessor的前置处理完成后就会进入本阶段。
如果Bean在Spring配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。
3.BeanPostProceesor 后置处理
postProcessAfterInitialzation: 这个函数会在InitialzationBean完成后执行,因此称为后置处理。
4. BeanPostProceesor 后置处理 if(mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
通过以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。
第四步:销毁阶段
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》