@Lazy和代理bean如何影响Spring的循环依赖?

时间:2019-06-17 03:37:38

标签: java spring lazy-loading circular-dependency

让我们看下面的示例

    @Service
    class AServiceImpl{

         @Autowired
         BService bservice
    }

    @Service
    class BServiceImpl{

         @Autowired
         AService aservice
    }

我知道Spring使用三级缓存来解决循环依赖问题。当初始化A并注入B时,Spring开始初始化B,这需要注入A的bean。但是A尚未完全初始化,因此B只能从缓存中获取对A的未完全初始化的bean的引用。

但是在Spring中,如果AService带有@Transactional批注,Spring将使用BeanPostProcessor为A构造一个代理Bean,此过程发生在@Autowired之后。这意味着,尽管B引用了缓存中对A的未完全初始化的Bean的引用,但该引用并未指向代理Bean,这似乎是不正确的。我的推理有什么问题吗?

有一种说法,@ Lazy可以解决春季循环依赖问题。根据我的理解,此注释的用法有两种。

@Lazy
@Service
class AServiceImpl{

     @Autowired
     BService bservice
}

@Service
class BServiceImpl{

     @Lazy
     @Autowired
     AService aservice
}

对此注释的某些解释是,如果被另一个bean引用了带注释的bean,它将被初始化。但是我认为无论有没有它,“如果被另一个bean引用,带注释的bean总是会被初始化”,那么它如何解决循环依赖问题呢?

其他一些解释说带注释的bean如果调用其方法将被初始化,这听起来很合理,但是我尝试了一下,在我看来,即使没有调用AService中的任何方法,B仍然可以保留对它的引用。 AService的最终代理bean,我的尝试有什么问题?

1 个答案:

答案 0 :(得分:0)

另一种方法是在constructor

@Autowired
public AService(@Lazy BService bservice) {
    this.bservice = bservice;
}
  

不是完全初始化bean,而是创建一个代理以将其注入到另一个bean中。注入的bean仅在第一次需要时才完全创建。