Spring中,Bean生产、销毁过程代表一个Bean的生命周期。
Bean创建的生命周期
xx.class—>无参构造方法(存在多个时,spring会自己推断使用构造方法)—>实例化前—>实例化普通对象—>实例化后—>依赖注入(即:属性赋值)—>初始化前(@PostConstruct)—>初始化(InitializingBean)—>初始化后(AOP)—>代理对象—>Bean对象(如果进行AOP处理,此处是代理对象)
实例化前、后,都是使用InstantiationAwareBeanPostProcessors三个方法(BeanPostProcess的子接口)
1.前:可以自定义实例过程(postProcessBeforeInstantiation方法完成)
2.后:(postProcessAfterInstantiation方法完成)
属性注入
3.spring默认属性注入,(byName使用set方法名、byType根据参数类型)
4.@Autowrite方式属性注入操作:(postProcessProperties方法完成)
初始化前、后,都是使用BeanPostProcess接口完成
BeanPostProcess
IOC初始化扫描阶段,识别BeanPostProcess类型实现类,并实例化,将实例化的BeanPostProcess暂存到List中。
在普通类初始化前、后,循环调用,对普通类进行额外操作
AOP代理对象
生产代理类—>代理对象—>代理对象target属性赋值(target=普通对象)
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
AOP就是利用BeanProcessor上面方法进行实现的,在postProcessAfterInitialization方法中生成代理对象,并返回
标记那些对象需要进行AOP代理
切面bean(使用@Aspect @Component注解标记),也是一个bean。
在扫描阶段会被遍历,获取所有被切面标记的bean,并进行缓存。在这些被标记的bean初始化后阶段,对这些Bean进行AOP操作。
AOP操作完成后,代理对象会被缓存,后续使用时,使用代理对象。
BeanFactoryPostProcessor、BeanProcessor、Aware接口实现原理
都是在Spring执行过程中,通过判断对象类型(通过instanceof关键字),然后类型强转,进行调用接口方法
前言
利用Spring管理实例Bean,首先从单例池中获取Bean。
- 获取到,直接返回。
- 获取不到,开始Bean生成过程。在执行完初始化后,添加到单例池中。
一、Bean生成过程
1.生成BeanDefinition
Spring启动时,调用org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan扫描指定包路径,得到BeanDefinition集合,最终存放到:
beanDefinitionMap:存放原始的BeanDefinition
beanDefinitionNames:存放已经注册的类名。实例化时,用于递归生成实例对象
扫描阶段会创建BeanPostProcesser类型bean,并使用List缓存。处理普通Bean的初始化(前后)逻辑,循环调用所有BeanPostProcessor。
加载过程
类扫描流程
CachingMetadataReaderFactory解析某个.class文件得到MetadataReader对象是利用的ASM技术,类并没有加载到JVM。最终得到的ScannedGenericBeanDefinition对象。
其中beanClass属性存储的是当前类的名字,而不是class对象。(beanClass属性的类型是Object,它即可以存储类的名字,也可以存储class对象。在加载类步骤中,被赋值为class对象)
获取BeanDefinition方式
除了,通过扫描得到BeanDefinition对象。还可以通过直接定义BeanDefinition,或解析spring.xml文件的
MetadataReader元数据读取器
主要包含了一个AnnotationMetadata属性,功能有
1. 获取类的名字、
2. 获取父类的名字
3. 获取所实现的所有接口名
4. 获取所有内部类的名字
5. 判断是不是抽象类
6. 判断是不是接口
7. 判断是不是一个注解
8. 获取拥有某个注解的方法集合
9. 获取类上添加的所有注解信息
10. 获取类上添加的所有注解类型集合
2.合并BeanDefinition
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
通过扫描得到所有BeanDefinition之后,因为Spring中支持父子BeanDefinition合并操作,执行完合并操作,就可以根据BeanDefinition创建Bean对象。
在Spring中支持父子BeanDefinition合并操作,会重新生成一个BeanDefinition(RootBeanDefinition),而不是选择一个修改。
mergedBeanDefinitions:存放合并后的BeanDefinition,用于实例化对象。
合并步骤
1. 检查是否完成合并。(在mergedBeanDefinitions尝试获取)
2. 根据BeanName,从beanDefinitionMap中,获取当前容器的BeanDefinition
3. 检查BeanDefinition.getParentName属性,判断是否存在BeanDefinition继承关系。存在则进行属性合并。
4. 使用beanDefinitionMap中BeanDefinition,对新生成的RootBeanDefinition相同属性进行覆盖。
3.加载类
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
合并完成后,依次加载当前BeanDefinition对应的class(前期使用ASM技术,并未真正加载class),进行实例化操作。
加载之前,BeanDefinition的beanClass属性,存储的还是字符串。加载完成后,beanClass属性被重新赋值为Class对象。
ClassUtils.getDefaultClassLoader()
- 优先返回当前线程中的ClassLoader
- 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
- 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器
4.实例化前
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
目前Spring容器,持有的对象是Class对象。实例化过程:是将Class对象变成实例Bean
在此(实例化之前)阶段,可以利用InstantiationAwareBeanPostProcessor进行实例化前控制。如果postProcessBeforeInstantiation方法返回结果,则不会继续后续实例化动作(例如:属性注入、初始化),直接执行初始化后逻辑(一般用于支持AOP逻辑处理)。【与factoryBean类似】
源码分析
//【实例化前】动作。
//如果存在实例化前扩展,且有返回值。则直接继续执行【初始化后扩展】
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
//是否存在实例化前操作接口(InstantiationAwareBeanPostProcessor,实例化前调用,可用自己的实例化过程代替spring的过程)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//执行实例化前动作
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//**执行了实例化前扩展后,直接直接初始化后扩展点。(一般用于AOP逻辑处理)**/
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
//【实例化前】动作。
//如果存在实例化前扩展,且有多个返回值,只会返回一个。
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
//如果多个实现,仅需要一个有返回值
if (result != null) {
return result;
}
}
}
return null;
}
5.实例化
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
根据BeanDefinition创建实例。
singletonObject:一级缓存池
earlySingletonObject:二级缓存池
singletonFactories:三级缓存池
完成步骤12(初始化),实例bean才会加入单例池中
5.1.Supplier调用
首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。
作用,目前没搞清楚,感觉是利用JDK函数式接口,增加的一个扩展
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {//判断BeanDefinition中是否设置了Supplier
return obtainFromSupplier(instanceSupplier, beanName);
}
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(beanName);
try {
instance = instanceSupplier.get();//调用Supplier的get()得到对象
} finally {
if (outerBean != null) {
this.currentlyCreatedBean.set(outerBean);
} else {
this.currentlyCreatedBean.remove();
}
}
if (instance == null) {
instance = new NullBean();
}
BeanWrapper bw = new BeanWrapperImpl(instance);
initBeanWrapper(bw);
return bw;
}
5.2.工厂方法调用
若没有设置Supplier,则检查BeanDefin ition中是否设置了factoryMethod,也就是工厂方法,有两种方式可以设置factoryMethod。
@Bean所定义的BeanDefinition,也支持factoryMethod和factoryBean的
使用示例
5.3.推断构造方法
1.选择构造方法以及查找入参对象。
2.判断在对应的类中是否存在使用@Lookup注解的方法。
如果存在则把该方法封装为LookupOverride对象并添加到BeanDefinition中。
3.在实例化时,
如果当前BeanDefinition中没有LookupOverride,则直接用构造方法反射得到实例对象。
如果存在LookupOverride对象,即存在@Lookup注解了的方法,则会生成一个代理对象
5.4.SmartInitializingSingleton
当所有非懒加载Bean实例化完成后。会循环判断实例对象是否实现SmartInitializingSingleton。如果实现则执行afterSingletonsInstantiated
//1.完成所有非懒加载bean实例化后。2.递归单例池对象,判断是否实现SmartInitializingSingleton接口。
for (String beanName : beanNames) {
//从单例池中获取实例
Object singletonInstance = getSingleton(beanName);
//实例化完成后,判断实例化的bean是否实现了SmartInitializingSingleton
// 可以作为InitializingBean的替代方案,它在 bean 的本地构造阶段结束时被触发
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
//【【所有非懒加载bean实例化完成后,进行调用】】
smartSingleton.afterSingletonsInstantiated();
}
}
}
6.BeanDefinition后置处理
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法,可以修改合并后的BeanDefinition.
例如可以调用BeanDefinition的setInitMethodName手动添加初始化方法,一般不这么干。
注入依赖准备工作
调用AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition,查找注入点(@Autowired、@Value、@Inject标记的属性、方法),进行缓存,为后续属性注入做准备
调用CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition,查找注入点(@Resource标记的属性与方法),进行缓存。为后续属性注入做准备
7.实例化后
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
目前Spring容器,已经完成实例化(将Class对象变成实例Bean),所以postProcessAfterInstantiation参数是实例的对象与BeanName.目前实例对象的属性还没有赋值。
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
8.属性(依赖)注入
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
执行完实例化后的逻辑后。
继续执行
1.执行Spring内部(已过期的)依赖注入逻辑。(依赖set方法。框架没有侵入性。)
2.调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法处理:@Autowired、@Resource、@Value注解。(识别注解,有一定的侵入性)
Spring通过实现InstantiationAwareBeanPostProcessor,将依赖注入组件化。如果需要扩展,只需要继续实现InstantiationAwareBeanPostProcessor即可
//todo 1.根据注入点进行注入
//利用 InstantiationAwareBeanPostProcessor#postProcessProperties 处理spring自动注入动作
//调用AutowiredAnnotationBeanPostProcessor,对注入点(@Autowired、@Value、@Inject标记的属性、方法),进行属性注入
//调用CommonAnnotationBeanPostProcessor,对注入点(@Resource标记的属性与方法),进行属性注入
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//【利用反射技术】进行属性注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//过期方法
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
9.属性解析
10.执行Aware
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
完成属性赋值之后,(如果当前Bean实现了指定Aware)Spring会执行一些回调,包括:
- BeanNameAware:回传beanName给bean对象。
- BeanClassLoaderAware:回传classLoader给bean对象。
BeanFactoryAware:回传beanFactory给对象。
11.初始化前
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
BeanPostProcessor
InitDestroyAnnotationBeanPostProcessor会在初始化前,执行@PostConstruct的方法,
ApplicationContextAwareProcessor会在初始化前,执行其他Aware的回调:
- EnvironmentAware:回传环境变量
- EmbeddedValueResolverAware:回传占位符解析器
- ResourceLoaderAware:回传资源加载器
- ApplicationEventPublisherAware:回传事件发布器
- MessageSourceAware:回传国际化资源
- ApplicationStartupAware:回传应用其他监听对象,可忽略
ApplicationContextAware:回传Spring容器ApplicationContext
源码实现
//循环调用BeanPostProcessor
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
12.初始化
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
检查当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
- 执行BeanDefinition中指定的初始化方法
13.初始化后
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
源码与初始化前调用类似,只是调用BeanPostProcessor#postProcessAfterInitialization方法。
14.BeanPostProcessor调用
- InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
- 实例化
- MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
- 自动注入
- InstantiationAwareBeanPostProcessor.postProcessProperties()
- Aware对象
- BeanPostProcessor.postProcessBeforeInitialization()
- 初始化
- BeanPostProcessor.postProcessAfterInitialization()
二、Bean销毁过程
org.springframework.beans.factory.support.AbstractBeanFactory#registerDisposableBeanIfNecessary
SpringBean销毁,是在Spring容器正常关闭时触发。而不是垃圾回收时触发。
非原型Bean才有销毁逻辑。因为原型Bean不会再容器中存储,不存在销毁
Spring销毁逻辑
1.实现DisposableBean(或AutoCloseable)接口。
2.使用@PreDestroy注解,标记方法1.销毁Bean信息收集(创建Bean时完成收集)
信息收集,发生在初始化后,并存入disposableBeans中(LinkedHashMap)protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean.getClass() != NullBean.class &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
- 判断当前Bean是否实现DisposableBean、AutoCloseable接口、BeanDefinition中是否指定了destroyMethod。[DisposableBeanAdapter.hasDestroyMethod(bean, mbd)]
- 调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断[DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()]
- ApplicationListenerDetector中直接使得ApplicationListener是DisposableBean
- InitDestroyAnnotationBeanPostProcessor中使得拥有@PreDestroy注解了的方法就是DisposableBean
把符合上述任意条件的Bean,包装成DisposableBeanAdapter对象,并存入disposableBeans中(LinkedHashMap)
2.Spring容器关闭过程
关闭容器。context.close()
- 首先发布ContextClosedEvent事件
- 调用lifecycleProcessor的onCloese()方法
- 销毁单例Bean
- 遍历disposableBeans
- 把每个disposableBean从单例池中移除
- 调用disposableBean的destroy()
- 如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean
- 如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉 (inner bean参考https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-inner-beans)
- 清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName
- 清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组
- 清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean
- 遍历disposableBeans