让我们看下面的示例
@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,我的尝试有什么问题?
答案 0 :(得分:0)
另一种方法是在constructor
中@Autowired
public AService(@Lazy BService bservice) {
this.bservice = bservice;
}
不是完全初始化bean,而是创建一个代理以将其注入到另一个bean中。注入的bean仅在第一次需要时才完全创建。