Spring循环依赖问题

Spring循环依赖问题

1.什么是循环依赖问题
比如 Order 类中有一个 user属性 User 类中有一个 order 属性

@Component
public class Order {
     
    @Autowired
    private User user;
}

@Component
public class User {
     
    @Autowired
    private Order order;
}

这就产生了循环依赖问题

  1. 怎么解决循环依赖问题
    首先我们看源码,三级缓存主要指:
    /** Cache of singleton objects: bean name --> bean instance(缓存单例实例化对象的Map集合) */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

    /** Cache of singleton factories: bean name --> ObjectFactory(单例的工厂Bean缓存集合) */
    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);

    /** Set of registered singletons, containing the bean names in registration order(单例的实例化对象名称集合) */
    private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
    /**
     * 添加单例实例
     * 解决循环引用的问题
     * Add the given singleton factory for building the specified singleton
     * if necessary.
     * 

To be called for eager registration of singletons, e.g. to be able to * resolve circular references. * @param beanName the name of the bean * @param singletonFactory the factory for the singleton object */ 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); } } }

这三级缓存分别指:
singletonFactories : 单例对象工厂的cache
earlySingletonObjects :提前暴光的单例对象的Cache
singletonObjects:单例对象的cache

  1. 为什么要使用三级缓存 ? 二级缓存是否能解决循环依赖的问题
    一级缓存:
    一级缓存和二级缓存中存放的是不同类型的对象,如果只有一级缓存,那么成品和半成品都会放到一起,在调用过程中,可能会获取到半成品

二级缓存:
足以解决循环依赖的问题了,那么为什么还要使用三级缓存呢?
如果在循环依赖的过程中,不包含aop动态代理的话,那么直接使用二级缓存足以解决问题,但是当出现了aop动态代理之后,必须要使用三级缓存

三级缓存:
通过反射的方式创建的普通对象一定会创建,只不过当需要动态代理的时候,会完成当前对象的替换工作
在整个容器中,可能同时存在普通对象和代理对象,但是暴露给别人使用的一定是最终版本的对象(要么品普通对象,要么是代理对象

Spring循环依赖问题_第1张图片
Spring循环依赖问题_第2张图片

你可能感兴趣的:(Spring,java,spring)