这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战
Spring 源码分析系列
- Spring源码分析-IOC基本概念
- Spring源码分析-IOC核心组件
- Spring源码分析-IOC源码分析(一)
- Spring IOC源码分析-obtainFreshBeanFactory(二)
- Spring IOC源码分析-invokeBeanFactoryPostProcessors (三)
- Spring IOC源码分析-registerBeanPostProcessors(四)
- Spring IOC源码分析-finishBeanFactoryInitialization
前言
Bean的生命周期是面试Spring框架必问的考点, 在 BeanFactory 接口注释上就描述了, 一个Bean对象从工厂生产到最后消亡的全部过程. 我们不看源码其实也可以思考一下, 一个对象重创建到消亡需要做些什么?
我们可能会想到首先当然是创建对象, 实例化当然是调用构造函数, 实例化之后, 然后我们需要去做一些初始化的操作, 比如设置一些非构造函数属性的值, 当对象用完了然后就是销毁. 当然Spring Bean不一样因为会存在Bean的依赖, 在初始化之前会多一步属性填充,
Spring Bean的生命周期其实也是对象创建的过程, 可以划分为4个阶段和多个扩展点
Bean的生命周期
Spring 源码注释上已经描述了Bean的生命周期
Bean销毁的过程
Spring Bean的生命周期分为四个阶段
和多个扩展点
。扩展点又可以分为影响多个Bean
和影响单个Bean
1.1 四个阶段
- 实例化 Instantiation
- 属性赋值 Populate
- 初始化 Initialization
- 销毁 Destruction
源码分析: 前三个阶段的源码, 都在 AbstractAutowireCapableBeanFactory #doCreateBean 方法实现的.
createBeanInstance 实例化
populateBean 属性注入和initializeBean 初始化Bean方法 上面实例化Bean的方法是在getBean()方法中调用的, 而getBean是在finishBeanFactoryInitialization方法中调用的,用来实例化单例非懒加载Bean.
销毁Bean阶段: 是在容器关闭时调用的,详见 ConfigurableApplicationContext#close()
1.2 生命周期扩展点
生命周期扩展点非常多,按照影响Bean的范围分类
1.2.1 影响多个Bean
- BeanPostProcessor
- InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor作用于实例化阶段的前后,BeanPostProcessor作用于初始化阶段的前后。
1.2.2 影响单个Bean
1. Aware接口, 分为两组Aware Group1 和Aware Group2
一堆的Aware接口, Aware是一个具有标识作用的超级接口,实现该接口的bean是具有被spring 容器通知的能力的,而被通知的方式就是通过回调。也就是说:直接或间接实现了这个接口的类,都具有被spring容器通知的能力。
1.1 Aware Group1
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
Aware Group2
- EnvironmentAware
- EmbeddedValueResolverAware
- ApplicationContextAware( 这个接口又包含了ResourceLoaderAware,ApplicationEventPublisherAwareMessageSourceAware)
EmbeddedValueResolverAware 该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。
ApplicationContextAware ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware 返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口.
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
// ....
}
Aware扩展点调用时机源码分析
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 1. 调用的是Group1中的三个Bean开头的Aware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 这里调用的是Group2中的几个Aware,
// 而实质上这里就是前面所说的BeanPostProcessor的调用点
// 与Group1中的Aware不同,这里是通过BeanPostProcessor(ApplicationContextAwareProcessor)实现的。
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2. 生命周期
- InitializingBean
- DisposableBean
InitializingBean 顾名思义,是初始化Bean相关的接口。
afterPropertiesSet()方法是在初始化过程中被调用的。 InitializingBean 对应生命周期的初始化阶段,在上面源码的invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。
三种实现指定初始化方法的方法:
-
使用@PostConstruct注解,该注解作用于void方法上
-
在配置文件中配置init-method方法
<bean id="User" class="com.br.spring.demo.dto.User" init-method="init2">
<property name="name" value="boren"></property>
</bean>
- 实现InitializingBean接口
@Component
public class UserBean implements InitializingBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//1.使用PostConstruct注解
@PostConstruct
public void init(){
System.out.println("执行 init方法");
}
//2.在xml配置文件中配置init-method方法
public void init2(){
System.out.println("执行init2方法 ");
}
//3.实现InitializingBean接口
public void afterPropertiesSet() throws Exception {
System.out.println("执行init3方法");
}
}
最后
Spring 生命周期的四个阶段, 实例化, 属性注入, 初始化, 销毁和Spring 核心扩展点 Aware 和 生命周期接口 InitializingBean , DisposableBean