Spring
1. Spring 容器的加载过程
Refresh
-
this.prepareRefresh();
准备容器,设置容器的基本属性值
-
this.obtainFreshBeanFactory();
创建一个
BeanFactory
工厂,读取配置文件中的BeanDefinition
-
this.prepareBeanFactory(beanFactory);
上一个步骤只是简单的得到一个
BeanFactory
工厂,这一步是对工厂进行属性赋值
this.postProcessBeanFactory(beanFactory);
空方法,留给子类进行拓展操作
this.invokeBeanFactoryPostProcessors(beanFactory);
调用
BeanFactory
处理器,BeanFactoryPostProcessor
。
this.registerBeanPostProcessors(beanFactory);
准备实例化阶段需要的
BeanPostProcessors
this.initMessageSource();
为上下文初始化
message
源,即不同语言的消息体,国际化处理
this.initApplicationEventMulticaster();
初始化事件监听多路广播器。(通过多路广播器监听Bean对象在什么阶段去做什么样的事情)
this.onRefresh();
留给子类初始化其他Bean对象。
-
this.registerListeners();
注册监听。在所有注册的bean中查找
listener bean
,注册到消息广播器中 -
this.finishBeanFactoryInitialization(beanFactory);
初始化对象。
getBean==>doGetBean==>getSingleton/createBean==>doCreateBean==>createBeanInstrance//addSingletonFactory/populateBean/initialzeBean
-
this.finishRefresh();
> 在所有注册的`bean`中查找`listener bean`,注册到消息广播器中
对应,初始化阶段,先执行 aware
,然后再执行beanPostProcessors
2. Spring Bean 的生命周期
初始化Bean的先后顺序为
BeanPostProcessor的postProcessBeforeInitialization方法
类中添加了注解@PostConstruct 的方法
InitializingBean的afterPropertiesSet方法
bean的指定的初始化方法: init-method
BeanPostProcessor的postProcessAftrInitialization方法
3. Spring的循环依赖
3.1 什么是Spring的循环依赖
问题描述:
Spring中存在两个类(类A和类B),A对象中有B对象,B对象中有A对象;
public class A{ private B b; } public class B{ private A a; }
Spring容器在初始化时,如何解决这两个Bean的循环依赖问题?
3.2 Spring 中Bean的创建流程
Spring 中 Bean 的创建是分为 实例化和初始化两个步骤的(也只有这样分为两个步骤,才能解决循环依赖的问题)
实例化:仅仅只是完成对象堆空间的开辟,不完成对象属性的赋值
初始化:对对象的属性完成赋值操作
接下来,我们用图解来表示出循环依赖A,B对象的创建过程
3.3 核心步骤&核心代码
在我们对上面图片中的对象创建过程进行代码讲解时,我们需要先熟练掌握下面的几段代码块
step1:
Spring容器进行对象A的实例化
step2:
实例化的过程中,先会去判断容器中是否有bean对象了(getSingleton():依次从一级缓存到二级缓存到三级缓冲中获取是否存在bean对象);
step3:
此时容器中没有Bean对象的缓存,所以需要去new一个新的A对象;
this.getSingleton(beanName, () -> {return this.createBean(beanName, mbd, args);}
step2:
实例化完A对象后instanceWrapper.getWrappedInstance();
,将数据(半成品A)放入三级缓存中
半成品:仅仅完成了实例化,未完成初始化
this.addSingletonFactory(beanName, () -> { return this.getEarlyBeanReference(beanName, mbd, bean); }); protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized(this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { //放入三级缓存 key:beanName为A,value:lambda表达式 this.singletonFactories.put(beanName, singletonFactory); //移除二级缓存 beanName为A this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }
step3:
三级缓存中放入对象后,进行充A中的B属性this.populateBean(beanName, mbd, instanceWrapper);
的操作
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { ...... if (pvs != null) { this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); } } protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { .... Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); ..... } public Object resolveValueIfNecessary(Object argName, @Nullable Object value) { .... return this.resolveReference(argName, ref); .... } private Object resolveReference(Object argName, RuntimeBeanReference ref) { .... bean = this.beanFactory.getBean(resolvedName); ... }
step4:
尝试去获取B对象的缓存,此时容器中没有Bean对象的缓存,所以需要去new一个新的B对象;
public Object getBean(String name) throws BeansException { return this.doGetBean(name, (Class)null, (Object[])null, false); } protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { .... Object sharedInstance = this.getSingleton(beanName); ... }
step5:
实例化完B对象后instanceWrapper.getWrappedInstance();
,将数据(半成品B)放入三级缓存中;
step6:
三级缓存中放入对象后,填充B中的A属性this.populateBean(beanName, mbd, instanceWrapper);
step7:
同样,尝试从缓存中获取A对象来填充B中A的属性,因为之前A对象已经放入三级缓存中了,所以可以直接从缓存中取出A对象的半成品赋值给B对象;
step8:
当成功从三级缓存中获取到A对象时,会将A对象方法二级缓存中,并且从三级缓存中移除A
protected Object getSingleton(String beanName, boolean allowEarlyReference) { .... //从三级缓存中获取对象 ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); //当三级缓存中的对象Map<String,ObjectFactory>不为空时 //ObjectFactory为函数式接口 if (singletonFactory != null) { //调用Lambda表达式中的方法 singletonObject = singletonFactory.getObject(); //将Key,value放入二级缓存中 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } return singletonObject; }
step9:
B对象中的A对象(只完成实例化的半成品)的赋值完成,此时B对象已经是一个完成品(已实例化,已初始化,初始化中的A对象为半成品);(此时B对象已完成,所以我们要继续step3
的操作,进行A对象中B对象的赋值操作)。但是在继续step3
操作之前,会先调用addSingleton()
(将三级缓存中的B对象移除,放入一级缓存中);
protected void addSingleton(String beanName, Object singletonObject) { synchronized(this.singletonObjects) { //放入一级缓存beanName: B value:完成品的B对象 this.singletonObjects.put(beanName, singletonObject); //移除二级、三级缓存 this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }
step10:
B对象已完成创建且赋值,A中B属性的赋值,只需要将返回的对象,赋值给B属性。即完成了循环依赖;
step11:
A对象完成赋值操作后,创建操作完成,调用addSingleton()
;,将完成品的A对象放入一级缓存中,移除二三级缓存的A对象;
step12:
此时Spring容器中的缓存里,已经存储有A,B对象的完成品,且完成了循环依赖,上面介绍了A对象创建过程中Spring容器的流程(A对象创建的过程中顺便完成了B对象的创建,并且放到了缓存中)。我们的目的是创建A,B对象,接下来,B对象的创建,Spring尝试从缓存中获取B对象。此时我们发现,B对象的缓存已经存在于Spring容器中,直接返回B对象即可;
核心代码
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* Return an instance (possibly shared or independent)
* of the object managed by this factory.
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
T getObject() throws BeansException;
}
public class DefaultSingletonBeanRegistry{
//缓存对象:一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//缓存对象:三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//缓存对象:二级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//尝试从一级缓存中获取对象
Object singletonObject = this.singletonObjects.get(beanName);
//判断一级缓存中对象是否为空 且 为正创建中的对象
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//尝试从二级缓存中获取对象
singletonObject = this.earlySingletonObjects.get(beanName);
//判断二级缓存中对象是否为空
if (singletonObject == null && allowEarlyReference) {
synchronized(this.singletonObjects) {
//尝试从一级缓存中获取对象
singletonObject = this.singletonObjects.get(beanName);
//判断一级缓存中对象是否为空
if (singletonObject == null) {
//尝试从二级缓存中获取对象
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
//从三级缓存中获取对象
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
//当三级缓存中的对象Map<String,ObjectFactory>不为空时
//ObjectFactory为函数式接口
if (singletonFactory != null) {
//调用Lambda表达式中的方法
singletonObject = singletonFactory.getObject();
//将Key,value放入二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
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 (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//调用lambda表达式
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
}
public class AbstractAutowireCapableBeanFactory{
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
//调用createBean方法
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
//实例化Bean对象
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//调用addSingletonFactory方法,传入形参 bean和ObjectFactory的实现类
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
//填充属性(填充A对象中的B对象属性或者B对象中填充A对象的属性)
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
......
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
.....
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
.....
/**
* public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
* return this.resolveReference(argName, ref);
* }
*
* private Object resolveReference(Object argName, RuntimeBeanReference ref) {
* .....
* //从工厂中获取Bean对象
* bean = this.beanFactory.getBean(resolvedName);
* .......
* }
* public Object getBean(String name) throws BeansException {
* //再次调用doGetBean方法。递归循环调用
* return this.doGetBean(name, (Class)null, (Object[])null, false);
* }
*/
}
}
public class DefaultSingletonBeanRegistry{
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
//判断一级缓存中是否含有key为beanName的数据
if (!this.singletonObjects.containsKey(beanName)) {
//key:lambda表达式放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
//二级缓存中移除key
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
}
三级缓存解决循环依赖问题的关键是什么?为什么通过提前暴露对象能解决问题?
通过实例化和初始化分开操作,在中间过程中给其他对象赋值的时候,并不是一个完整对象,而是把半成品对象赋值给了其他对象。
如果只使用一级缓存能不能解决问题?
不能,在整个处理过程中,缓存中放的是半成品和成品对象,如果只有一级缓存,那么成品和半成品都会放到一级缓存中,有可能在获取过程中获取到半成品对象,此时半成品对象是无法使用的。因此要把半成品和成品的存放空间区分开。
只使用二级缓存行不行,为什么需要三级缓存?
如果能保证所有的Bean对象都不调用getEarlyBeanReference
此方式,使用二级缓存可以吗?
是的,如果保证都不调用就可以只使用二级缓存。
使用三级缓存的本质就在于解决aop
代理问题
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
//代码A
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
//代码A处方法的实现类就有AbstractAutoProxyCreateor。ibp.getEarlyBeanReference方法就是获取代理对象。
为什么三级缓存就可以解决这个问题?
当一个对象需要被代理的时候,在整个创建过程中是包含两个对象,一个普通对象,一个代理对象。Bean默认都是单例,那么在整个生命周期处理的环节中, 一个BeanName
是不能对应两个对象的。所以在处理的过程中,需要判断动态的进行代理。getEarlyBeanReference
方法中就是动态的进行代理。
参考文档:
B站:Spring源码深度解析31精讲,阿里P8架构师讲解的太牛了!