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;
}