Spring循环依赖源码解析
个人记录,有误指出
什么是循环依赖?
比如:A对象依赖了B对象,B对象又依赖了A对象
class A {
@Autowired
private B b;
}
class B {
@Autowired
private A a;
}
以Bean生命周期的形式描述循环依赖过程:
1、在singletonsCurrentlyInCreation中存储A,表示A正在创建,
2、A实例化得到A的原始对象,将原始对象生成代理对象的lambda表达式放到第三级缓存<aName, A原始对象>
3、进行依赖注入,此时A依赖了B,
4、填充B属性(进行getBean()),从单例池中找对应bName对应的Bean,找不到并且发现A正在创建中(在一个if表达式上面:isSingletonCurrentlyInCreation),代表A出现了循环依赖,然后去第二级缓存中找,找不到,并且allowEarlyReference默认为true,然后去第三级缓存中找,找到的是一个lambda表达式,然后执行lambda表达式(wrapIfNecessary()方法就是执行AOP的方法,会判断你是否有切面),对A进行AOP,得到A代理对象,然后将A代理对象保存到第二级缓存当中,
5、填充其他属性
6、A初始化——>(判断是否提前进行AOP)——>AOP——>代理对象
循环依赖用到的集合
1、singletonsCurrentlyInCreation记录是否正在创建的Bean
2、earlyProxyReferences记录是否Bean提前进行过AOP
3、一级缓存为:singletonObjects
4、二级缓存为:earlySingletonObjects
5、三级缓存为:singletonFactories
doGetBean()
A Bean在创建的时候,会使用lambda表达式,把createBean()方法作为形参传到getSingleton()方法中
// 根据Scope去创建bean
// Create bean instance.
if (mbd.isSingleton()) {
// 获取单例bean,如果获取不到则创建一个bean,并且放入单例池中
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;
}
});
// sharedInstance可能是一个FactoryBean,所以需要单独再去factoryBeanObjectCache中去获取对应的对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
getSingleton()
在getSingleton()方法中,会调用beforeSingletonCreation()方法对该创建的Bean存到一个Set集合当中,该singletonsCurrentlyInCreation集合存放的就是正在创建的A Bean的beanName,在getSingleton方法中后面的finally代码块中会将该singletonsCurrentlyInCreation集合中存放打beanName进行remove移出。
该getSingleton()方法主要的作用是执行lambda表达式,将创建的bean添加到单例池,然后返回bean。
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);
// 如果不存在实例,则创建单例bean实例
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 + "'");
}
// 把当前正在创建的beanName添加到singletonsCurrentlyInCreation中,singletonsCurrentlyInCreation是一个Set
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// singletonFactory是外面传进来的lambda表达式,执行lambda表达式
// 创建单例bean
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;
}
// 将刚刚正在创建的beanName从singletonsCurrentlyInCreation中移除
afterSingletonCreation(beanName);
}
// 将创建好的单例bean添加到单例池singletonObjects中
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
doCreateBean()
如果判断当前创建的是单例bean,并且存在于singletonsCurrentlyInCreation的Set集合中,则表示该bean正在创建中,则表示该bean进行了循环依赖,将该Bean的原始对象,封装在lambda表达式中作为value,beanName作为key添加到第三级缓存singletonFactories中。
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 如果当前创建的是单例bean,并且允许循环依赖,并且还在创建过程中,那么则提早暴露
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 此时的bean还没有完成属性注入,是一个非常简单的对象
// 构造一个对象工厂添加到singletonFactories中
// 第四次调用后置处理器
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // AService
// addEarlySingleton(beanName, bean);
}
向第三级缓存singletonFactories添加的时候,同时将第二级缓存的beanName进行remove移出,实现原子性,二级和三级缓存只能有一个HashMap存放beanName(防止程序出现bug,生成了多个单例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)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName); // 已经创建成功的单例列表
}
}
}
在doGetBean()方法中,会在createBean前前去单例池中寻找该Bean,发现单例池中不存在,并且发现该Bean正在创建当中,去二级缓存earlySingletonObjects中寻找,发现为空,去第三级缓存singletonFactories中寻找,执行lambda表达式,返回的代理对象添加到二级缓存中,并且在第三级缓存中删除lambda表达式。
这里防止多个循环依赖同时执行第三级缓存的lambda表达式产生多个代理对象,使用了synchronized锁,所以单例池使用的是ConcurrentHashMap,而第二级和第三级使用的是HashMap,为了提高效率。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// singletonsCurrentlyInCreation存放正在创建的bean
// isSingletonCurrentlyInCreation为true表示该bean正在创建
// singletonObject一级缓存单例池根据beanName中找不到bean
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 没有earlySingletonObjects会怎么样?
// 在earlySingletonObjects二级缓存中根据beanName尝试找bean
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 为什么需要singletonFactories?
// 尝试在三级缓存中根据beanName寻找bean
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// bean实例化得到原始对象的时候就会添加到singletonFactories三级缓存中,所以一般不为null
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject(); // 执行lambda AOp
// 因为二级缓存和三级缓存中只能存在一个,为了保证原子性
// 所以添加进二级缓存后,在三级缓存中删除
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
lambda表示,进行AOP,将进行AOP的bean添加进earlyProxyReferences【是一个ConcurrentHashMap,循环引用时记录是否提前生成了代理对象,key:beanName,value:bean的原始对象】
// bean原始对象
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName); // beanName aService
// 判断
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey); //代理对象
}
wrapIfNecessary()
判断是否已经生成代理对象,在实例化前能够实现创建一个代理对象,并且在targetSourcedBeans中存储,所以先判断是否存在于targetSourcedBeans中,如果存在则直接返回代理对象,如果不存在,则根据切面和Bean原始对象创建一个代理对象
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// beanName不为空,并且beanName存在于targetSourcedBeans中,表示这个bean被动态代理了
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 当前这个bean不用被代理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础bean,或者@Aspect修饰的类不需要被代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 获取当前beanClass所匹配的advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果匹配的advisors不等于null,那么则进行代理,并返回代理对象
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 基于bean对象和Advisor创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 存一个代理对象的类型
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
doCreateBean()部分
在Bean的生命周期到初始化后时,会重新判断是否需要AOP
// Initialize the bean instance.
// 对象已经暴露出去了
Object exposedObject = bean;
try {
// 3、填充属性 @Autowired
populateBean(beanName, mbd, instanceWrapper);
// 4、 初始化 和 BeanPostProcessor
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) {
// 在解决循环依赖时,当AService的属性注入完了之后,从getSingleton中得到AService AOP之后的代理对象
Object earlySingletonReference = getSingleton(beanName, false); // earlySingletonObjects
if (earlySingletonReference != null) {
// 如果提前暴露的对象和经过了完整的生命周期后的对象相等,则把代理对象赋值给exposedObject
// 最终会添加到singletonObjects中去
if (exposedObject == bean) { // ②分析二:
exposedObject = earlySingletonReference;
}
// 如果提前暴露的对象和经过了完整的生命周期后的对象不相等
// allowRawInjectionDespiteWrapping表示在循环依赖时,只能
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// AService的原始对象被注入给了其他bean,但是AService最后被包装了
// 也就是说其他bean没有用到AService的最终版本
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
①分析一:postProcessAfterInitialization()
进入AOP方法,首先会检验是否在生命周期:初始化
后之前是否有提前进行过AOP,检查earlyProxyReferences中是否存在该Bean,没有则进行wrapIfNecessary()方法进行创建代理对象,有则返回bean。
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// earlyProxyReferences中存的是哪些提前进行了AOP的bean,beanName:AOP之前的对象
// 注意earlyProxyReferences中并没有存AOP之后的代理对象 BeanPostProcessor
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 没有提前进行过AOP,则进行AOP
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
// 为什么不返回代理对象呢?
return bean; //
}
②分析二:
在经过初始化生命周期后,检验当前Bean是否和创建的的原始Bean是否相等,相等则赋值第二级缓存存储的代理对象
// 在解决循环依赖时,当AService的属性注入完了之后,从getSingleton中得到AService AOP之后的代理对象
Object earlySingletonReference = getSingleton(beanName, false); // earlySingletonObjects
if (earlySingletonReference != null) {
// 如果提前暴露的对象和经过了完整的生命周期后的对象相等,则把代理对象赋值给exposedObject
// 最终会添加到singletonObjects中去
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}