Spring源码解读--(二、Spring如何判断构造器注入时的循环依赖)

   需要了解循环依赖以及Spring检测到构造器的循环依赖的问题,可以看这篇博文:https://www.cnblogs.com/bhlsheji/p/5208076.html

    首先同样是AbstractBeanFactory类的:

doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)方法。

(注:要了解Spring如何实例化一个对象可以看写的上一篇博文。)

这里直接进入这个方法的单例创建:

源码:

    if(mbd.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

进入this.getSingleton方法:

源码:

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

由这两段源码可以知道,当出现循环依赖,就会循环调用,当然,如果是其它方式的循环依赖,由于能够直接完成对象初始化只是没有赋值,同时三级缓存提前曝光,所以就能解决这个循环,但构造器注入时产生循环,由于不能初始化对象,所以不能解决这个循环,但spring会检查到这个循环并抛出异常:

例如这两个类:

@Service/*("ous")*/
public class House {

    private HouseService houseService;

    @Autowired
    public House(HouseService houseService){
        this.houseService = houseService;
    }

}

@Service
public class HouseService {

//    @Autowired
//    @Qualifier("ous")
    private House house;

    @Autowired
    public HouseService(House house){
        this.house = house;
    }

}

当创建初始化HouseService调用this.createBean(beanName, mbd, args),由于需要对象House,所以去初始化House,然后House和HouseService一样去初始化通过doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)方法,调用 this.getSingleton方法,之后通过 singletonObject = singletonFactory.getObject();调用this.createBean(beanName, mbd, args)。

由与这里通过singletonFactory.getObject();的调用,导致this.createBean(beanName, mbd, args)的循环调用,所以一直不会走到

               finally {
                    if(recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }

                    this.afterSingletonCreation(beanName);
               }

循环检测的关键方法是this.beforeSingletonCreation(beanName)方法与this.afterSingletonCreation(beanName);

也就让正在创建的Bean总是不能完成初始化,也就不能运行this.afterSingletonCreation方法进行remove。

源码:

    protected void beforeSingletonCreation(String beanName) {
        if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }

    protected void afterSingletonCreation(String beanName) {
        if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
            throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
        }
    }

this.singletonsCurrentlyInCreation是:

private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));

       

由于是Set不能添加相同的Key所以会添加是失败,然后抛出BeanCurrentlyInCreationException异常。

至于Spring如何通过构造器初始化对象,也先不展开说明了,这里为了以后研究一些详情,先记录一下调用堆栈信息,以防忘记:

关键类:AutowiredAnnotationBeanPostProcessor

1、AbstractBeanFactory类的getBean方法

             if(mbd.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

2、AbstractAutowireCapableBeanFactory类的:createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法

     beanInstance = this.doCreateBean(beanName, mbdToUse, args);

3、doCreateBean方法的:

        if(instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

4、createBeanInstance方法的:
       return this.autowireConstructor(beanName, mbd, ctors, args);

5、产生一个对象ConstructorResolver

protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
        return (new ConstructorResolver(this)).autowireConstructor(beanName, mbd, ctors, explicitArgs);
    }

6、对象ConstructorResolver的autowireConstructor方法

argsHolder = this.createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, this.getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);

7、

convertedValue = this.resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, (TypeConverter)converter, fallback);

8、

return this.beanFactory.resolveDependency(new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);

9、

result = this.doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);

10、

instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);

11、

   return beanFactory.getBean(beanName);

之后则是循环去获取另一个Bean,当是构造器初始化时则产生循环并抛出异常。

猜你喜欢

转载自blog.csdn.net/qq_25179481/article/details/89241914
今日推荐