Spring系列(四) 循环依赖那些事

随着我们代码中更多服务的出现与依赖关系的耦合,bean与bean之间的交互往往会涉及很多对其他类的依赖。我们通常用简单的Autowired、提供对应依赖对象的setter方法以及构造器中传入需要引用的其他对象,spring就可以完美的做好依赖关系自动装配。那么本节就来分析下spring中是如何完成bean之间这些依赖的自动查找与注入

关于这个话题,最重要的是spring中用到的三级缓存。但spring中的循环依赖情况分很多种,本文会进行不同场景的依次分析。

一级缓存:singletonObjects (存放的是已经完成整个生命周期初始化的对象,是正常getBean方式拿出来的源头)

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

二级缓存:earlySingletonObjects (暂时放的是通过各种方式实例化出来的对象,属性及初始化方法及后置处理等过程还未进行)

/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

三级缓存:singletonFactories (允许提前暴露引用下用于创建bean的工厂,在代码体现上是一个lamda方法:()->createBean(beanName, mbd, args))

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

单例与单例setter依赖

在spring中,创建的bean如果不指定scope一般默认为单例的。注解依赖方式包括字段级别注解及方法级别注解两种情况,常见A,B依赖代码如下

Bean1:

@Component
public class BeanSetter1 {
   
    @Autowired
    private BeanSetter2 beanSetter2;
     public void print(){
   
        System.out.println("autowired beanSetter2:"+beanSetter2);
    }
//@Autowired
//    public void setBeanSetter2(BeanSetter2 beanSetter2) {
   
 //       this.beanSetter2 = beanSetter2;
  //  }
//}

Bean2:

@Component
public class BeanSetter2 {
   
    @Autowired
    private BeanSetter1 beanSetter1;
    public void print(){
   
        System.out.println("autowired beanSetter1:"+beanSetter1);
    }
 //   @Autowired
//    public void setBeanSetter1(BeanSetter1 beanSetter1){
   
//        this.beanSetter1 = beanSetter1;
//    }
}

启动容器,通过context拿到对应的bean以及其中注入的依赖。其中BeanSetter1与BeanSetter2中的属性都与容器中各自对应的beanSetter是同一个单例对象
在这里插入图片描述
对于singleton类型的bean,spring在创建context时会完成对该bean的实例化、初始化、后置处理等一系列过程。在refresh中的finishBeanFactoryInitialization中就是负责对所有满足条件的bean进行预先创建及缓存过程。
判断条件如下: 非抽象、单例、非懒加载。对FactoryBean还需要满足允许提早初始化
在这里插入图片描述
在上面流程中,当beanName为beanSetter1时,getBean() 开始进行BeanSetter1的创建及初始化

缓存获取

第一次从singletonObjects缓存中拿,同时允许查找提前引用缓存allowEarlyReference->singletonFactories
DefaultSingletonBeanRegistry

	public Object getSingleton(String beanName) {
   
		return getSingleton(beanName, true);
	}

可惜现在bean才开始创建并不在缓存中也还未设置开始创建等状态,所以拿出来为空直接返回。接着为创建该bean做一些bd的清除及状态设定
markBeanAsCreated

clearMergedBeanDefinition(beanName)
this.alreadyCreated.add(beanName);

按照bean的scope类型进行不同方式的创建

if (mbd.isSingleton()) {
   
   sharedInstance = getSingleton(beanName, () -> {
   
						...
							return createBean(beanName, mbd, args);
						...
					);
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

创建bean的开始

在getSingleton中,第二次尝试从singletonObjects中拿依然为空,此时经过bean创建前期的一系列检验及状态的标记后调用ObjectFactory进行bean的真正创建即createBean(beanName, mbd, args)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   
Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
   
				if (this.singletonsCurrentlyInDestruction) {
   
					throw new BeanCreationNotAllowedException...
				}
				//检验当前bean是否可以创建的:不在inCreationCheckExclusions名单中且成功加入singletonsCurrentlyInCreation中的。(在ConfigurationClassEnhancer中会通过setCurrentlyInCreation对该两种名单设置)
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				try {
   
				//真正完成bean创建、初始化、后置处理及代理替换的入口
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
   
				...
				}
				catch (BeanCreationException ex) {
   
					...
				}
				finally {
   
					...
					//不在inCreationCheckExclusions名单中并从在创建bean名单中移除
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
   
			//将完成所有过程的bean放置到一级缓存singletonObjects,并从其他缓存中移除
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
}

对于objectFactory创建bean的过程进行分析,
AbstractAutowireCapableBeanFactory

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
   
	//1.解析beanClass,找到需要创建的类型是什么
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
//2.进行方法override方法的查找与设置
mbdToUse.prepareMethodOverrides();
//3.调用当前容器中是否有后置处理器InstantiationAwareBeanPostProcessor的applyBeanPostProcessorsBeforeInstantiation能提前得到对象(并一起完成applyBeanPostProcessorsAfterInitialization)提前结束,一般用于给使用者通过配置或者自定义获得一个代理对象(大部分情况都是null)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
   
	return bean;
}
}
//4. 进行具体创建bean的流程处理
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance 

接下来分析doCreateBean的实现过程
AbstractAutowireCapableBeanFactory

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
   
//1.从factoryBeanMethodCache中拿或者创建一个,主要是factoryBean情况下
BeanWrapper instanceWrapper =  this.factoryBeanInstanceCache.remove(beanName)
or 
//其中允许提供自定义构造方式obtainFromSupplier、factoryMethodName实例化,构造参数注入及默认实例化等方式直接创建。
//在@Configuration中使用@Bean方式下定义的bean创建可以用factor
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值