200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Spring循环依赖解决源码解析

Spring循环依赖解决源码解析

时间:2018-12-20 10:55:14

相关推荐

Spring循环依赖解决源码解析

Spring循环依赖解决

无法解决的循环依赖的方式循环依赖解决原理----三级缓存解决步骤 相关方法

无法解决的循环依赖的方式

1) Spring无法解决构造方法注入引起的循环依赖问题

2) Spring无法解决多例对象的循环依赖问题,因为多例对象是不进行缓存的

循环依赖解决原理----三级缓存

//第一级缓存:缓存已经完成了实例化和属性设置的单例对象(单例对象缓存)private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);//第二级缓存:缓存完成了只完成实例化,没有设置依赖属性的单例对象(早期暴露的单例对象缓存)private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);//第三级缓存:缓存单例对象的对象工厂引用,工厂封装了生成对象的逻辑(单例对象工厂缓存)private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

解决步骤

doGetBean方法执行{//1.分别从三级缓存获取对象,第三级缓存命中会提升到缓存到二级Object sharedInstance = getSingleton(beanName); //2.以下方法调用会先触发createBean方法创建BeansharedInstance = getSingleton(beanName, () -> createBean(beanName, mbd, args) //3. createBean调用 doCreateBean//4.然后doCreateBean调用addSingletonFactory方法将创建的Bean封装在工厂引用中,放入三级缓存中//5.doCreateBean继续执行调用 populateBean方法设置属性,属性依赖Bean会触发继续调用doGetBean方法创建Bean,直到循环依赖的Bean被创建完,设置好依赖属性//6.结束doCreateBean后继续步骤2方法执行会调用addSingleton将Bean缓存到第一级缓存,清除二三级缓存doCreateBean调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));然后执行populateBean(beanName, mbd, instanceWrapper)设置属性,如果有依赖的Bean没有创建会触发doGetBean方法去创建依赖的Bean}

相关方法

public Object getSingleton(String beanName) {return getSingleton(beanName, true);}protected Object getSingleton(String beanName, boolean allowEarlyReference) {//从一级缓存中获取实例: 一级缓存用于缓存已经完成实例化的单例BeanObject singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {//从二级缓存中获取: 二级缓存用于缓存已经实例化的Bean,但是还没有设置依赖的类singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {//从三级缓存获取:三级缓存用于缓存单例工厂,工厂封装了对应的创建Bean的方法ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//从工厂中获取单例singletonObject = singletonFactory.getObject();//放入二级缓存中this.earlySingletonObjects.put(beanName, singletonObject);//从三级缓存移除this.singletonFactories.remove(beanName);}}}}return singletonObject;}protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {//将刚刚创建的Bean封装到ObjectFactory中,保存到三级缓存this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {//Map缓存生成的单例名称与实例的映射this.singletonObjects.put(beanName, singletonObject);//移除缓存单例工厂,工厂是一个lamda表达式,可创建对应的实例对象this.singletonFactories.remove(beanName);//循环依赖时候暂时缓存未赋值完成的单例类,这里创建完成后移除缓存this.earlySingletonObjects.remove(beanName);//LinkedHashSet缓存已经注册了的单例Bean名称,用于检测重复注册的名字this.registeredSingletons.add(beanName);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。