spring容器
文章目录
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
,也就是在初始化后生成代理对象,直接返回,二级缓存为空,只用到了三级缓存和一级缓存
下面是转载一位大神的AOP入口,待以后学习aop
转载链接 : https://blog.csdn.net/forever_ddaxx/article/details/105608020
上一篇: CSS3重要知识点解析