zoukankan      html  css  js  c++  java
  • Spring循环依赖

    Spring是如何解决循环依赖的?

    • 三级缓存
    //一级缓存,用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
    //二级缓存 存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
     private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    
     //三级缓存 存放 bean 工厂对象,用于解决循环依赖
     private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    
    • bean的创建会调用doCreateBean方法
    1. 先调用addSingletonFactory方法
    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);
    		}
    	}
    }
    
    1. 再调用getSingleton方法
    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);
    				}
    			}
    		}
    	}
    	return singletonObject;
    }
    
    1. 最后调用addSingleton方法
    protected void addSingleton(String beanName, Object singletonObject) {
    	synchronized (this.singletonObjects) {
    		this.singletonObjects.put(beanName, singletonObject);
    		this.singletonFactories.remove(beanName);
    		this.earlySingletonObjects.remove(beanName);
    		this.registeredSingletons.add(beanName);
    	}
    }
    

    总结

    • A先实例化(存入三级缓存),A初始化是发现依赖了B
    • B实例化(存入三级缓存),B初始化发现依赖了A,缓存中取得了A后删除三级缓存中的A并存入二级缓存,B初始化完成,B存入一级缓存.
    • 继续初始化A,由于B已经初始化完成,A也初始化完成,删除二级三级缓存.
  • 相关阅读:
    webstorm如何调试vue项目的js
    Js调用本地exe的方式
    IE浏览器中使用js调用cmd命令行demo
    JS Array.reverse 将数组元素颠倒顺序
    webstorm 2018.2.5最新激活方式
    Vmware12安装centos系统详解
    如何查看电脑系统版本信息和显示文件后缀名
    怎样用命令行开启或关闭Windows服务
    Vue编写的todolist小例子
    Word如何发布文章到博客园开源中国网易博客
  • 原文地址:https://www.cnblogs.com/qifengle1412/p/12757723.html
Copyright © 2011-2022 走看看