文章目录
BeanFactory体系
先来一张图压压惊,由上图可见DefaultListableBeanFactory为集大成者,实现了所有接口,具备容器的基本功能,所以下文中提到的bean容器都指的是DefaultListableBeanFactory。下面对BeanFactory接口的继承体系简单进行介绍。
- BeanFactory
bean 容器的顶级接口,该接口定义了容器提供的基本功能。getBean(String beanName)--->根据名称获取bean
注意:此处只提供了获取单个bean实例的功能
BeanFactory的直接子接口:
HierarchicalBeanFactory, ListableBeanFactory, AutowireCapableBeanFactory
- HierarchicalBeanFactory
具备分层能力的工厂,主要增加getParentBeanFactory()方法,所谓的父子容器
- ListableBeanFactory
具备获取多个bean实例功能的工厂 ,主要增加
String [] getBeanNamesForType(Class<T> classType)--->获取bean容器中指定类型的bean名称集合,所谓面向接口,所以可能存在多个实现类的实例
Map<String,T> getBeanOfType(Class<T> classType)--->获取bean容器中指定类型的bean实例集合
- AutowireCapableBeanFactory
具备装备能力的工厂,增加autowireBean(),createBean(Class<T> classType)...等相关方法
IOC源码解析
前置知识:
getBean步骤
- 实例化 Instantiation
3种方式 :
### Supplier接口 ()
### 静态工厂方法和工厂实例方法 (@Bean注解的方法会走这里哦)
### ~有参构造 ~无参构造(一般是无参)
- 属性填充 Population
注入属性,所谓DI(依赖注入),@Value @Autowired @Resource等
- 初始化 Initialization
此处会按顺序完成如下操作:
### invokeAwareMethods (各种回调)
### postProcessBeforeInitialization (@PostConstruct)
@PostConstruct会被 CommonAnnotationBeanPostProcessor---->InitDestroyAnnotationBeanPostProcessor #postProcessBeforeInitialization方法处理
### afterPropertiesSet (InitializingBean) , 然后init-method
### postProcessAfterInitialization (除循环依赖的AOP入口)
三级缓存
-
singletonObjects ---------- IOC容器
Map singletonObjects = new ConcurrentHashMap<>(256) ---> 一级缓存
-
earlySingletonObjects ---------解决循环依赖的过渡容器
Map earlySingletonObjects = new HashMap<>(16) ---> 二级缓存
注意: 正常的bean
创建或者循环依赖
(AB都不是代理对象)正常来说不需要二级缓存过渡的, 但是循环依赖中有代理对象的时候, 需要二级缓存缓存一下proxy对象,具体后续会讲到…
-
singletonFactories --------- 刚创建的对象放入的初始容器
Map singletonFactories = new HashMap<>(16) ---> 三级缓存 ### 存放的是ObjectFactory的匿名内部类实例, 一个获取提前暴露的单例bean引用的回调`getEarlyBeanReference()`,此处画重点,因为这个方法就是解决循环依赖中的代理对象的关键
具体源码:
主流程getBean
此抽象类实现了getBean()
,内部调用doGetBean
(),该方法的主要处理流程如下:
###### AbstractBeanFactory (getBean的实现类) 代理就贴一些重要的地方出来了
protected <T> T doGetBean() {
/*
* 去掉name的前缀"&"
* 从aliasMap中获取bean的原始名称 解决aliasA--->aliasB--->ABean多重别名的情况
*/
final String beanName = transformedBeanName(name);
// 一级缓存去获取bean
/*
*------------注意这是第一个getSingleton(beanName)方法------------11111111111111
* 此时bean还未在创建状态,相当于去一级缓存拿bean , 肯定没有 返回null
*/
Object sharedInstance = `getSingleton` (beanName);
//存在的话直接返回
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}else {
//不存在的话
//这里去父容器里面拿 , 目前没有子父容器一说 只有一个容器 这里忽略
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//重复dogetbean 一样的逻辑
return ((AbstractBeanFactory) parentBeanFactory).doGetBean()
}
//-----------创建bean的地方-----------------
try {
//父类和子类的beandefinition合并
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//depend-on 循环依赖报错
String[] dependsOn = mbd.getDependsOn();
...throw new BeanCreationException
// Create bean instance.
/*
*-----------此处是第二个getSingleton(beanName,ObjectFactory)-----222222222222
* 这个重载方法主要就是做2件事情,
* 1.ObjectFactory#Object方法 , 也就是createBean()
* 2.createBean回调完成后, 将返回的bean放进一缓存,同时删除二级和三级缓存
*/
if (mbd.isSingleton()) {
sharedInstance = ``getSingleton``(beanName, () -> {
return createBean(beanName, mbd, args);});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//name前缀有& , 返回FactoryBean,没有的话,调用sharedInstance.getObject()方法返回真正的bean
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
return (T) bean;
}
第一个getSingleton
一级缓存(ioc容器)拿bean
```DefaultSingletonBeanRegistry#getSingleton````
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
// 重载方法一
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从一级缓存中获取单例对象
Object singletonObject = this.singletonObjects.get(beanName);
//因为isSingletonCurrentlyInCreatio为fasle 后面不会走了,当前没有在创建当中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {...............}
return singletonObject;
}
}
第二个getSingleton
回调ObjectFactory.getObject方法 ,创建bean的实际逻辑全在这里() -> {return createBean(beanName, mbd, args);})
,创建完最后会统一把返回的bean放进一级缓存
```DefaultSingletonBeanRegistry#getSingleton````
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
//添加beanName到正在创建的容器中
beforeSingletonCreation(beanName);
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
//移除正在创建的容器的beanName
afterSingletonCreation(beanName);
if (newSingleton) {
//创建完最后会统一把返回的bean放进一级缓存
addSingleton(beanName, singletonObject);
}
}
}
createBean()
````AbstractAutowireCapableBeanFactory # createBean````
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
/*
* BeanWrapper 是一个基础接口,由接口名可看出这个接口的实现类用于包裹 bean 实例。
* 通过 BeanWrapper 的实现类可以方便的设置/获取 bean 实例的属性
*/
````AbstractAutowireCapableBeanFactory # createBean````
protected Object doCreateBean(){
/*
* 创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。createBeanInstance
* 中包含三种创建 bean 实例的方式:
* Supplier接口 ()
* 态工厂方法和工厂实例方法 (@Bean注解的方法会走这里哦)
* ~有参构造 ~无参构造(一般是无参)
*
* 若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB
* 增强 bean 实例。
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 此处的 bean 可以认为是一个原始的 bean 实例,暂未填充属性
/*
* earlySingletonExposure 是一个重要的变量,这里要说明一下。该变量用于表示是否提前暴露
* 单例 bean,用于解决循环依赖。earlySingletonExposure 由三个条件综合而成,如下:
* 条件1:mbd.isSingleton() - 表示 bean 是否是单例类型
* 条件2:allowCircularReferences - 是否允许循环依赖
* 条件3:isSingletonCurrentlyInCreation(beanName) - 当前 bean 是否处于创建的状态中
*
* earlySingletonExposure = 条件1 && 条件2 && 条件3
* = 单例 && 是否允许循环依赖 && 是否存于创建状态中。
* 默认为ture , 也就是会走下面的逻辑
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 添加工厂对象到 singletonFactories(三级缓存)
/*
* 这个getEarlyBeanReference是解决循环依依赖获取bean对象或者proxy的地方
*---------这个方法很重要,也是为什么要三级缓存,而不是二级缓存的关键点--------
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference();
}
});
}
Object exposedObject = bean;
try {
// 向 bean 实例中填充属性,populateBean 方法也是一个很重要的方法
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
/*
* 进行余下的初始化工作,详细如下:
* 1. 判断 bean 是否实现了 BeanNameAware、BeanFactoryAware、
* BeanClassLoaderAware 等接口,并执行接口方法
* 2. 应用 bean 初始化前置操作 (@PostConstruct)
* 3. 如果 bean 实现了 InitializingBean 接口,则执行 afterPropertiesSet
* 方法。如果用户配置了 init-method,则调用相关方法执行自定义初始化逻辑
* 4. 应用 bean 初始化后置操作 (AOP入口)
*
* 另外,AOP 相关逻辑也会在该方法中织入切面逻辑,此时的 exposedObject 就变成了
* 一个代理对象了
*/
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
// 此处要画一个重点,我刚开始看这里的时候忽略掉了
if (earlySingletonExposure) {
/**
*--------- 第三处getSingleton()------------------ 3333333333333333333333
* 返回的可能为proxy对象 , 也可能是愿对象 , 去的是二级缓存拿bean
*/
Object earlySingletonReference = ```getSingleton```(beanName, false);
// 只有循环依赖的bean才会走的逻辑
if (earlySingletonReference != null) {
/*
* 如果完成初始化之后的bean与提前暴露的bean相等时,提前暴露的bean是target
* 因为在初始化时后置处理器的postProcessAfterInitialization()方法处理可能创建代理对象
* 不创建代理对象的原因有两种 :
* 1.bean本身不需要被代理
* 2.getEarlySingletonReference中被代理并添加到earlyProxyReferences中,此时会跳过代理直接返回原始对象, 循环依赖才会触发getEarlyBeanReference,循环依赖中有代理条件才会传教proxy
* 此处若相等,则说明postProcessAfterInitialization中未创建代理
* 进来这肯定都是循环依赖,所以直接把二级缓存中的bean返回(target或者proxy)
*/
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
//这里是错误的创建bean的逻辑了
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//exposedObject != bean说明postProcessAfterInitialization()返回的是代理对象
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 如果依赖了当前对象A的对象B发现依赖的对象A是原始对象,则报错,因为容器中真正准备放的是代理对象A @Async注解存在循环依赖且使用不当的时候可能会报这个错误,因为此种方式代理对象的创建是通过postProcessAfterInitialization()完成的,在getEarlyBeanReference()不会对代理对象进行创建
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
return exposedObject;
}
第三个getSingleton
```DefaultSingletonBeanRegistry#getSingleton````//处理循环依赖的
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
//allowEarlyReference传进来的是fasle , 所以这里返回的是二级缓存的bean
if (singletonObject == null && allowEarlyReference) {.......}
}
}
return singletonObject;
}
getEarlyBeanReference
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// AOP创建代理对象的第二个入口 默认由AbstractAutoProxyCreator创建
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
}
流程图
注意 : 不是循环依赖的代理对象的创建是在postProcessAfterInitialization
,也就是在初始化后生成代理对象,直接返回,二级缓存为空,只用到了三级缓存和一级缓存
createBean:
- InstantiationAwareBeanPostProcessor:Object bean = resolveBeforeInstantiation(beanName, mbdToUse),创建 bean 的逻辑会走 createBean 方法,该方法中会先执行所有 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法尝试创建 bean 实例,如果成功创建,则会直接调用 postProcessAfterInitialization 方法初始化 bean 后返回;如果 InstantiationAwareBeanPostProcessor 没有创建 bean 实例,则会调用 doCreateBean 方法创建 bean 实例。在 doCreateBean 方法中,会先根据 bean 的 Class 中的构造器定义,决定如何实例化 bean ,如果没有定义构造器,则会使用无参构造器,反射创建 bean 对象。
- createBeanInstance 创建bean
- MergedBeanDefinitionPostProcessor:applyMergedBeanDefinitionPostProcessors(InitDestroyAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor),处理注入注解等
populateBean
- InstantiationAwareBeanPostProcessor:postProcessAfterInstantiation,postProcessAfterInstantiation 方法也是干预 bean 的属性等东西的。而且有一个小细节注意一下,postProcessAfterInstantiation 方法返回的是 boolean 类型,当 postProcessAfterInstantiation 返回 false 时,会直接 return 出去,不再执行下面的属性赋值 + 组件依赖注入的逻辑!(通常这个方法一定是返回 true 的,底层默认也是返回 true )------->>就是让咱在 bean 已经初始化好,但还没有开始属性赋值和依赖注入时切入自定义逻辑。
- InstantiationAwareBeanPostProcessor:postProcessProperties(AutowiredAnnotationBeanPostProcessor )
initializeBean
-
invokeAwareMethods(beanName, bean)
-
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 前置回调
- InitDestroyAnnotationBeanPostProcessor这个调用了**@PostConstruct**注解的方法
- ApplicationContextAwareProcessor:调用invokeAwareInterfaces
-
invokeInitMethods(beanName, wrappedBean, mbd): InitializingBean----->>>>initMetod
-
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 后置回调
- AbstractAutoProxyCreator:创建代理对象的关键
- ApplicationListenerDetector:用来关联所有的监听器引用
扩展点
invokeBeanFactoryPostProcessors
- ImportSelector/ImportBeanDefinitionRegistrar
- BeanDefinitionRegistryPostProcessor
自定义的 BeanDefinitionRegistryPostProcessor 执行时机比内置的 ConfigurationClassPostProcessor 要晚,这也是 SpringFramework 最开始的设计( ConfigurationClassPostProcessor 实现了 PriorityOrdered 接口,且优先级最高)
- BeanFactoryPostProcessor
registerBeanPostProcessors
finishBeanFactoryInitialization
- InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
从 bean 的创建阶段之前,就有
InstantiationAwareBeanPostProcessor
来拦截创建了,每个 bean 在创建之前都会尝试着使用InstantiationAwareBeanPostProcessor
来代替创建,如果没有任何InstantiationAwareBeanPostProcessor
可以拦截创建,则会走真正的 bean 对象实例化流程。在
InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
方法中,只能拿到 bean 对应的 Class 类型,以及 bean 的名称(当然啦,本来就是凭空造,有 Class 类型就够了),如果方法没有返回值,则代表InstantiationAwareBeanPostProcessor
不参与拦截 bean 创建的动作。
- SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
- MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
在 createBeanInstance 方法执行完毕之后,此时 bean 对象已经创建出来了,只是没有任何属性值的注入而已。此时 doCreateBean 方法会走到 applyMergedBeanDefinitionPostProcessors 方法,让这些 MergedBeanDefinitionPostProcessor 去收集 bean 所属的 Class 中的注解信息。三个关键的 MergedBeanDefinitionPostProcessor ,它们分别是 InitDestroyAnnotationBeanPostProcessor (收集 @PostConstruct 与 @PreDestroy 注解)、CommonAnnotationBeanPostProcessor (收集 JSR 250 的其它注解)、AutowiredAnnotationBeanPostProcessor (收集自动注入相关的注解)。
- InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
等这些 MergedBeanDefinitionPostProcessor 都工作完毕后,此时 bean 对象所属的 Class 中的信息都收集完毕了,接下来还得让 InstantiationAwareBeanPostProcessor 出场,它要负责控制是否继续走接下来的 populateBean 和 initializeBean 方法初始化 bean 。
- InstantiationAwareBeanPostProcessor#postProcessProperties
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 1414
不过这次它调用的是 postProcessProperties 方法,这个步骤会将 bean 对象对应的 PropertyValues 中封装赋值和注入的数据应用给 bean 实例。通常情况下,在该阶段 SpringFramework 内部起作用的后置处理器是 AutowiredAnnotationBeanPostProcessor ,它会搜集 bean 所属的 Class 中标注了 @Autowired 、@Value 等注解的属性和方法,并反射赋值 / 调用。CommonAnnotationBeanPostProcessor处理@Resource 注解
- BeanPostProcessor
接下来的两个动作就发生在 initializeBean 方法中了,它就是 BeanPostProcessor 的前后两个执行动作 postProcessBeforeInitialization 和 postProcessAfterInitialization 。进入到 initializeBean 方法后,bean 的生命周期已经到了初始化逻辑回调的阶段,此时 bean 中应该注入的属性均已完备,BeanPostProcessor 的切入也只是给 bean 添加一些额外的属性的赋值、回调等等,以及生成代理对象。
- SmartInitializingSingleton
它是在所有非延迟加载的单实例 bean 全部初始化完成后才回调的。这个阶段底层会取出所有实现了 SmartInitializingSingleton 接口的 bean ,去回调 afterSingletonsInstantiated 方法。而且当时小册还说了,这个设计只是为了让 BeanFactory 也能插一脚初始化的后处理,仅此而已。
下面是转载一位大神的AOP入口,待以后学习aop
转载链接 : https://blog.csdn.net/forever_ddaxx/article/details/105608020