Java @Lazy和代理bean如何影响Spring中的循环依赖关系?
让我们看看下面的例子Java @Lazy和代理bean如何影响Spring中的循环依赖关系?,java,spring,lazy-loading,circular-dependency,Java,Spring,Lazy Loading,Circular Dependency,让我们看看下面的例子 @Service class AServiceImpl{ @Autowired BService bservice } @Service class BServiceImpl{ @Autowired AService aservice } 我知道Spring使用三级缓存来解决循环依赖性问题。当A被初始化并且B被注入时,Spring开始初始化B,这需
@Service
class AServiceImpl{
@Autowired
BService bservice
}
@Service
class BServiceImpl{
@Autowired
AService aservice
}
我知道Spring使用三级缓存来解决循环依赖性问题。当A被初始化并且B被注入时,Spring开始初始化B,这需要注入A的bean。但是A还没有完全初始化,所以B只是从缓存中获取对A的未完全初始化bean的引用
但在Spring中,如果服务带有@Transactional注释,Spring将使用BeanPostProcessor为服务构造一个代理Bean,这个过程在@Autowired之后发生。这意味着,尽管B引用了一个来自缓存的未完全初始化的bean,但该引用并没有指向代理bean,这似乎是不正确的。我的推理有什么问题吗
有一种说法是@Lazy可以解决spring循环依赖问题。根据我的理解,这个注释有两种用法
@Lazy
@Service
class AServiceImpl{
@Autowired
BService bservice
}
或
对此注释的一些解释是,如果注释的bean被另一个bean引用,那么它将被初始化。但我认为,不管有没有它,“如果被另一个bean引用,带注释的bean将始终被初始化”,那么它如何解决循环依赖性问题呢
另一种解释是,如果调用了带注释的bean的方法,它将被初始化,这听起来很合理,但我尝试过,在我看来,即使没有调用AService中的任何方法,B仍然可以保留对AService的最终代理bean的引用,我的尝试有什么问题吗?另一种方法是在a中
它不会完全初始化bean,而是创建一个代理将其注入到另一个bean中。注入的bean只有在第一次需要时才能完全创建
另一种方法是在
它不会完全初始化bean,而是创建一个代理将其注入到另一个bean中。注入的bean只有在第一次需要时才能完全创建
对于
BeanPostProcessor
,Post
位基本上意味着“创建后”-因此,不是BeanPostProcessor
创建bean,而是负责在创建bean后处理(初始化)bean。所以B对A的引用仍然有效。在这些场景中,@PostConstruct注释也很有用,另请参见@racraman如果BeanPostProcessor通过jdk(InvocationHandler)或cglib(MethodInterceptor)创建了一个代理bean,那么它就不是以前的bean了,它是一个新的bean,以前的bean又是它的成员字段(目标对象),BeanPostProcessor
不创建bean,而是初始化它的一部分。例如,from:“BeanPostProcessor
实例对bean(或对象)实例进行操作。也就是说,Spring IoC容器实例化一个bean实例,然后BeanPostProcessor实例执行其工作。”注意“然后”.要使用字段注入解决循环依赖,我认为您不必使用@Lazyannotation@racraman如果BeanPostProcessor没有为用@Transactional
注释的类创建代理bean,那么如何以及何时创建和引用代理bean?对于BeanPostProcessor
,Post
位基本上意味着“创建后”——因此不是BeanPostProcessor
创建bean,而是负责在创建bean之后处理(初始化)bean。所以B对A的引用仍然有效。在这些场景中,@PostConstruct注释也很有用,另请参见@racraman如果BeanPostProcessor通过jdk(InvocationHandler)或cglib(MethodInterceptor)创建了一个代理bean,那么它就不是以前的bean了,它是一个新的bean,以前的bean又是它的成员字段(目标对象),BeanPostProcessor
不创建bean,而是初始化它的一部分。例如,from:“BeanPostProcessor
实例对bean(或对象)实例进行操作。也就是说,Spring IoC容器实例化一个bean实例,然后BeanPostProcessor实例执行其工作。”注意“然后”.要使用字段注入解决循环依赖,我认为您不必使用@Lazyannotation@racraman如果BeanPostProcessor没有为带有@Transactional
注释的类创建代理bean,那么代理bean是如何以及何时创建和引用的?我实际上是在询问基本原理/机制,不是替代方案。我实际上是在问原理/机制,不是替代方案。
@Service
class BServiceImpl{
@Lazy
@Autowired
AService aservice
}
@Autowired
public AService(@Lazy BService bservice) {
this.bservice = bservice;
}