spring怎样解决循环

对于控制反转来说,肯定需要通过反射技术来产生bean,当然那就有一个问题了,怎样解决循环依赖问题了,

一什么是循环依赖

循环依赖,简单来说就是在A类中有B类的实例,在B类中有A的实例,简单理解就是A依赖B,B依赖A,这样构成了环路。当然只要这种依赖构成环路,就可以是循环依赖。

二循环依赖的种类

按照属性赋值的地方,可以分为构造器循环依赖和setter或者带有Autowire注解的属性的循环依赖,二属性的循环依赖按照属性种类分为singleton循环依赖和prototype类型循环依赖。

三解决循环依赖的思考

要解决循环依赖,就必须了解bean的生命周期,在springbean的生命周期是:通过调用构造器产生对象,然后在注入属性,实现了BeanNameAwarej接口的通过这个接口关联ID,实现BeanFactoryAware的关联自己的工场,bean的后置处理器处理,配置了init-method进行init,交给bean的后置处理器处理,使用,实现了Diposiable接口的调用他的destroy和配置destroy-method的调用destroy销毁对象。如果要解决循环依赖,重点应该放在第一步和第二步之间。把实现了第一步的对象暴露出来。

所以如果是构造器的话,属性的赋值是在构造器里完成,这种就没法解决循环依赖,二配置了scope="prototype"意味着每次请求来都会创造一个对象,这种对象是没法做到提前暴露的。所以说能够解决就只有singleton的。

四spring解决循环依赖的方式

其实spring的思想和我们上面的思考很像,它使用三级缓存解决

一级缓存 singletonObjects,这主要是缓存那些初始化好的队形,这是一级缓存。earlySingletonObjects,主要缓存那些提前暴露的的对象,这是二级缓存,singletonFactories,这里存的是单例工场,这就是三级缓存。

三级缓存

/** Cache of singleton objects: bean name --> bean instance */

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** Cache of singleton factories: bean name --> ObjectFactory */

private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

/** Cache of early singleton objects: bean name --> bean instance */

private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

当一个bean在执行构造函数之后,就会进行第二步,如果是一个bean,就会在singletonObjects缓存区找,如果没有找到,就会去二级缓存earlySingletonObjects去找,如果还是没有找到,允许通过三级缓存,通过三级缓存singletonFactories的getBean(),然后把这个对象放入earlySingletonObjects里,把三级缓存里面的remove掉。

三级缓存代码实现

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);

            }

         }

      }

   }

isSingletonCurrentlyInCreation是判断对象是否在创建,allowEarlyReference这个决定是否可以从三级缓存里拿对象。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值