一、整体流程分析
图中是我整理的相关Bean创建流程,主要可以分为三层:
- AbstractBeanFactory定义了Bean创建的主流程
- DefaultSingletonBeanRegistry定了Singleton Bean注册的主流程
- AbstractAutowireCapableBeanFactory类提供了Bean 实例创建的具体方法.
下面将从以下几个方面来总结Bean创建的整个流程:
- Bean创建整体流程分析
- Bean创建具体内容分析-实例化、初始化、Bean创建流程中的扩展接口
- 循环依赖解决的原理
二、Bean创建整体流程说明
通过上面图的流程分析,我们看到Bean的创建过程,大致分为三个层次,下面分别看下者三个层次做了什么事情.
2.1.AbstractBeanFactory.doGetBean
AbstractBeanFactory的继承体系
AbstractBeanFactory主要作用如下:
- 实现Beanfactory接口:提供获取Bean的接口,触发Bean的创建工作
- 继承FactoryBeanRegistrySupport类,该类提供了SingletonBeanRegistry功能,即单例Bean的注册功能(Bean创建)
这就不难理解为什么要在,DefaultListableBeanFactory.preInstantiateSingletons()方法中触发用户定义的所有Bean的初始化了,因为DefaultListableBeanFactory持有了当前容器中用户定义的Bean的BeanDefinition信息和所有的beanName信息,那么只需要遍历,调用AbstractBeanFactory.getBean(beanName)就可以完成所有bean的创建了
AbstractBeanFactory类中Bean创建流程主要在doGetBean方法中,该方法主要逻辑如下:
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//1转换Bean名称
final String beanName = transformedBeanName(name);
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//2.1检查是否循环依赖,如果是,先获取依赖Bean的引用
....
}else{
//2.2正常创建
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果当前BeanFactory设置了父BeanFactory,交由父BeanFactory创建Bean
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//..父BeanFactory创建bean
}
//将beanName放到alreadyCreated集合,在该层中标记beanName对应的Bean正在创建 ,这个缓存和循环依赖没有关系
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//获取当前beanName对应的BeanDefinition类
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//处理@DependsOn 依赖的bean,也是根据beanName加载对应bean的流程
}
//singleton类型bean创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}else if (mbd.isPrototype()) {
//prototype类型Bean创建
}else{
//scope 类型Bean创建
}
// 是否需要根据给定的类型转化bean
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
}
2.1.1.alreadyCreated集合的作用:
用于存放当前已经开始创建Bean的beanname,因为在多线程的情况下,如果要是在创建Bean的过程中,有可能有的线程还在通过DefaultListableBeanFactory往容器内注册Bean的BeanDefinition,而Bean的初始化开始时,是在DefaultListableBeanFactory通过遍历beanDefinitionNames所有beanName进行注册Bean的,所以有可能会造成iterator不安全.
伪代码如下:
//容器ApplicationContext触发Bean的初始化流程
Map<String, BeanDefinition> beanDefinitionMap = new HashMap();
List<String> beanDefinitionNames = new ArrayList();
//加载了 BeanDefinition
....
preInstantiateSingletons(){
//开始初始化
for(String beanName : this.beanDefinitionNames){
getBean(beanName)
}
}
//这时如果并发的再注册Bean,那么beanDefinitionNames,动态添加将是不安全的.
2.1.2.Singleton类型Bean创建入口
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
在singleton类型分之,主要有这两个函数调用:
- getSingleton: 执行singleton实例的创建流程
- getObjectForBeanInstance:
- 如果getSingleton返回不是FactoryBean则,正常返回
- 如果是FactoryBean,则调用FactoryBean.getObject()方法
接下来看getSingleton方法.
2.2.DefaultSingletonBeanRegistry.getSingleton
以下是getSingleton方法代码:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
getSingleton方法内容比较简单,主要分为以下内容:
- 查看当前单例Bean集合singletonObjects中是否存在beanName对应的bean,如果存在直接返回
- 执行传入的ObjectFactory.getObject()方法,得到单例Bean实例
- 将单例Bean实例假加入到singletonObjects
其中ObjectFactory.getObject()方法就是AbstractBeanFactory中的createBean方法,是创建Bean实例的具体方法.
另外,DefaultSingletonBeanRegistry中还维护了spring 中bean创建过程中使用到的三个缓存集合:
- singletonObjects: 存放最终Bean的单例集合
- singletonFactories: 临时存放Bean创建过程中的FactoryBean
- earlySingletonObjects: 存放循环依赖的Bean引用
后面会讲到这三个集合是如何配合使用的.
2.3.AbstractAutowireCapableBeanFactory.createBean
再贴一次上面的流程图:
真正创建Bean时,经过以下几步:
- 是否存在InstantiationAwareBeanPostProcessor类型的BeanProcessor,在调用其postProcessBeforeInstantiation方法时,创建了一个自定义的Bean
- 如果是结束Bean创建流程,使用该Bean
- 否则,继续执行Bean创建流程
- 获得Bean对应Class的实例
- 处理循环依赖,暴露引用
- 属性填充(依赖注入)
- 执行初始化相关接口
- 注册Bean为DisposableBean
下面对每一步进行分析.
三、Bean创建具体流程
3.1.InstantiationAwareBeanPostProcessor
我们看下该类的注释:
This interface is a special purpose interface, mainly for
* internal use within the framework. It is recommended to implement the plain
* {@link BeanPostProcessor} interface as far as possible, or to derive from
* {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
* from extensions to this interface.
InstantiationAwareBeanPostProcessor这个接口是有特殊用途的,主要在spring框架内部使用.
一般推荐推荐使用BeanPostProcessor或InstantiationAwareBeanPostProcessorAdapter来实现增强bean的功能.
接口定义代码:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
方法说明:
- postProcessBeforeInstantiation: 在Bean实例化之前调用,默认返回null
- .如果返回不为null,那么Bean创建过程就会提前结束,并会接着调用所有的BeanPostProcessor.postProcessAfterInitialization
- 该方法不会作用到一个工厂方法
- postProcessAfterInstantiation实例化后调用,在执行属性注入是,首先被调用,这是属性还未注入.
- 该方法用于特殊属性注入.
- 如果返回false,当前Bean将不会执行后续的属性注入.
- postProcessPropertyValues: 当前属性注入的属性值集合
- 可以对特殊的属性进行修改,默认返回原有的属性集合
- 如果返回null,那么将跳过后续的属性注入逻辑.
特别注意:
spring中AOP实现AspectJAwareAdvisorAutoProxyCreator,就是该接口的子类.
3.2.Bean对应Class实例化方式
Bean对应Class实例化方式有以下几种:
- 使用Supplier返回一个实例
- 使用指定FactoryBean.工厂方法获取
- 使用有参构造函数或无参构造函数获取实例, 默认是无参构造函数
3.3.属性填充
在springBean创建过程中,对属性依赖注入,支持三种情况:
- AUTOWIRE_BY_NAME: 通过bean名称注入
- AUTOWIRE_BY_TYPE: 通过Bean类型注入,默认的注入方式
- AUTOWIRE_CONSTRUCTOR: 通过构造函数注入,会对构造器参数,进行自动bean注入,进而赋值到属性上.
3.4.初始化接口
Bean初始化接口主要分为三类:
- *Aware接口
- BeanPostProcessor接口
- postProcessBeforeInitialization
- postProcessAfterInitialization
- InitializingBean接口
执行顺序:
Aware接口->BeanPostProcessor.postProcessBeforeInitialization->InitializingBean接口->BeanPostProcessor.postProcessAfterInitialization
为什么是这个顺序?
- Aware接口一般是注入一些Spring维护的一些信息:如BeanName,BeanFactory等,这些一般是在类中以属性体现,可以算是Bean属性的一部分,只不过是通过Aware的方式注入.
- InitializingBean接口是开发者定义的一些逻辑,是在所有的属性值已经赋值完成时执行.
- BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法,可以在InitializingBean前后,对bean进行包装,如生成代理等.
- postProcessAfterInitialization还会在InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation返回不为null时执行,即提前终结bean创建时,也会被调用.
3.4.1.Aware接口
Bean在创建过程中会执行,以下三个Aware接口的调用:
- BeanNameAware : 设置BeanName
- BeanClassLoaderAware: 设置当前Beanfactory的ClassLoader
- BeanFactoryAware: 设置当前的BeanFactory
3.5.DisposableBean
在Bean创建的过程的最后阶段,Spring会把Bean包装成DisposableBeanAdapter,注册到DefaultSingletonBeanRegistry中的Map<String, Object> disposableBeans 集合中,用于在Spring的ApplicationContext关闭时,调用对应的destroy方法,执行Bean的销毁工作.
DisposableBeanAdapter.destroy方法代码如下:
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
它会调用bean上定义的destroy-method指定的方法.
四、FactoryBean原理
以具体例子来说明FactoryBean的原理:
@Component
public class FactoryBeanService implements FactoryBean<AddressService> {
@Override
public AddressService getObject() throws Exception {
System.out.println("AddressService");
return new AddressServiceImpl();
}
@Override
public Class<?> getObjectType() {
return AddressService.class;
}
}
public interface AddressService {
}
public class AddressServiceImpl implements AddressService {
}
当在执行Bean创建流程时,参考第一章部分,会首先创建一个FactoryBeanService对应的Bean,即:
singletonObjects集合中存在:
factoryBeanService-> factoryBeanService 对应的Bean
这是如果通过context.getBean(AddressService.class)或者通过@Autowire在别的Bean中注入AddressService时就会再次走Bean创建流程,创建AddressService对应的Bean,流程如下:
- 首先会遍历所有的当前容器中所有的beanDefinitionNames,查找有没有该类型对应的Bean,
- 因为当前Bean还不存在,并且它会有FactoryBean产生,
- 所以遍历到对应的FactoryBean即FactoryBeanService时,会调用FactoryBean的getObjectType()方法,发现匹配,返回对应FactoryBean的beanName.
- 根据返回的FactoryBean的beanName执行AbstractBeanFactory.doGetBean方法
- 因为当前已经存在FactoryBeanService对应的Bean,那么在Object sharedInstance = getSingleton(beanName);将不会返回null
- 执行getObjectForBeanInstance
- 调用FactoryBeanService的getObject()方法
- 将当前FactoryBeanService对应的beanName即factoryBeanService添加到factoryBeanObjectCache缓存中
总结:
- 先创建FactoryBean对应的Bean并放到singletonObjects集合
- 创建对应类型的Bean时,调用FactoryBean.getObject()方法
- 将当前FactoryBean对应的beanName和getObject返回的Bean的实例加入FactoryBean的缓存factoryBeanObjectCache中,防止反复调用getObject
五、循环依赖解决的原理
我们将通过上图来说明以下Spring解决循环依赖的原理.
首先,再次说下Spring三级缓存对应到代码中是,DefaultSingletonBeanRegistry中的:
- Map<String, Object> singletonObjects : 最终所有生成的单例Bean都会放到这里,可以叫做单例池,即上图中的S-Map
- Map<String, ObjectFactory<?>> singletonFactories: 提前暴露的工厂集合,即上图的SF-Map
- Map<String, Object> earlySingletonObjects : 需要提前实例化的单例集合,这个提前的含义后面会说.
下面我们通过上图和代码一起结合说明.
首先:循环依赖的代码在AbstractAutowireCapableBeanFactory.doCreateBean中.
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
...
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
...
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
在每个一个Bean实际创建时,都会执行这段代码:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
这块代码的含义的是,将一个ObjectFactory类型放到singletonFactories,即上面的SF-Map.
5.1.无循环依赖时简单singleton Bean创建
那么首先分析无循环依赖时,如何创建Bean A,步骤如下
第一步:
将Bean A对应的ObjectFactory对象放到singletonFactories,
第二步:
正常实例化Bean 对应的Class,执行属性注入、初始化接口调用
第三步:
当Bean创建完成,在第一章的总图中,第二张图,即DefaultSingletonBeanRegistry.getSingleton方法中,
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
addSingleton(beanName, singletonObject);这步,我们看下代码:
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
我们看到,将该bean的对应的beanName从singletonFactories移除,即刚才我们加入的ObjectFactory对象被移除,没有使用到,并且还会移除earlySingletonObjects中对应的内容,虽然也没有添加.
然后将beanName->bean 加入到singletonObjects,即完成当前bean的创建.
总结:
- 创建bean前首先把bean对应的ObjectFactory加入singletonFactories,
- bean创建完成,从singletonFactories移除,并加入到singletonObjects
5.1.有循环依赖时简单singleton Bean创建
假设现在如图中所示,A依赖B,B依赖A.
那么按照我们上面的流程,假如先创建A,则
- A对应的ObjectFactory先加入singletonFactories
- 继续进行创建A
- 属性注入(populateBean)时,发现需要B
- 创建B
- B对应的ObjectFactory先加入singletonFactories
- 继续创建B
- 属性注入(populateBean)时,发现需要A,这时就关键了
那么怎么找A呢?
Spring默认是按类型注入,这里假设我们没有做任何特别设置,那么也是按类型注入,那么将会进行如下步骤:
- 根据A的类型,找到容器中对应类型的BeanDefinition,并获取beanName
- 调用DefaultSingletonBeanRegistry.getSingleton(beanName)方法,这里就是循环依赖解决的关键
我们看下getSingleton这个方法:
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
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);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
这时调用的是
getSingleton(String beanName),也就是说调用getSingleton(String beanName, boolean allowEarlyReference)时,allowEarlyReference为true.
我们看下这个方法做了什么:
- 先从singletonObjects中找,因为这时A还未创建完成,所以这里返回null
- 接着从earlySingletonObjects找,因为这里我们也没有放,所以也是null
- 然后allowEarlyReference为true,这时我们就能从singletonFactories中找了,
- singletonFactories,我们在doCreatebean时已经放入了,时一个ObjectFactory
- 这时调用ObjectFactory.getObject(),返回一个对象
- 把该对象放入到earlySingletonObjects,并且从singletonFactories删除
从这里我们明白了earlySingletonObjects这个缓存的含义:
就是某一个Bean 例如A创建的过程中,由于循环依赖的存在提前需要执行完成一些操作,并且把操作后的对象 加入 Proxy A放到这里,使得当最开始的A属性注入完,可以继续执行后续的操作.
看下ObjectFactory.getObject()操作做了什么:
() -> getEarlyBeanReference(beanName, mbd, bean)
这是我们放入的ObjectFactory, getEarlyBeanReference 逻辑如下:
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;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
//SmartInstantiationAwareBeanPostProcessor
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
SmartInstantiationAwareBeanPostProcessor类的getEarlyBeanReference默认是返回传入的Bean.但是,如果SmartInstantiationAwareBeanPostProcessor
开启了AOP功能,并且当前Bean需要AOP功能,那么就会在AbstractAutoProxyCreator类中,对当前Bean进行代理包装,并将当前beanName加入earlyProxyReferences集合,返回代理类.
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
这时earlySingletonObjects中就会存在 beanName a->ProxyA
那么在原先A属性属性注入完,会怎么处理?
在初始化步骤,spring会执行BeanPostProcessor的postProcessAfterInitialization.时,一定会执行到AbstractAutoProxyCreator的postProcessAfterInitialization方法
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
而earlyProxyReferences就保存了之前在getEarlyBeanReference生成的ProxyA对应的beanName,那么就会直接放回当前bean.
这就是earlySingletonObjects存在的价值,为了解决含有代理逻辑的循环依赖解决方案.
下面用一个小图总结一下:
-
首先为A创建ObjectFactory 对象放入singletonFactories,所有正常单例bean都有这一步
-
如果存在循环依赖,则会被调用ObjectFactory.getObject()
- 如果存在代理逻辑,
- 那么生成代理,并将代理类维护到 一个代理类缓存里面,
- 返回代理类,加入到earlySingletonObjects
- 原有流程继续执行属性注入,然后在初始化接口调用时
- 如果存在代理逻辑,则
- 一定要调用到代理类创建逻辑,通过代理类缓存获取之前生成的代理,然后返回
- 如果存在代理逻辑,则
- 如果存在代理逻辑,
-
当创建Bean流程完成后,
- 将bean加入到singletonObjects单例池集合
- 从singletonFactories删除beanName和对应的ObjectFactory
- 从earlySingletonObjects删除beanName和对应的代理类