春天自动化了循环依赖

时间:2015-03-11 11:15:04

标签: spring aop spring-java-config spring-aspects

我正在使用带有@ComponentScan的java配置来初始化我的bean 和@EnableAspectJAutoProxy(proxyTargetClass=true)使用cglib代理。

在这个项目中,我们使用@Autowired在它们之间自动装配了许多生成的服务。它运作得很好。

但是,对于其中一些服务,我添加了@Async(我还在我的@EnableAsync(proxyTargetClass = true)课程中添加了@Configuration

之后,我得到了:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'ConversationUserLocalService': Bean with name 'ConversationUserLocalService' has been injected into other beans [ConversationUserHistoryLocalService] i
n its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'a
llowEagerInit' flag turned off, for example.

我想这是因为Spring在使用@Async方法注入服务之前BEFORE创建了代理。 这可能是个问题? 我应该怎么解决?

为了试图澄清我的问题,让我说我有:

@Service A,B& ç

A已自动装配B& C B已自动安装A& C C已自动安装A&乙

C的方法标记为@Async。

当Spring初始化applicationContext时,它会尝试初始化A,但需要B& C,所以它初始化它们。但毕竟,AOP试图建立C的代理(因为@Async),然后它检测到自动装配的C进入B,而A与C的代理不同,所以它失败了。

我希望这可以解释一下发生了什么。

4 个答案:

答案 0 :(得分:30)

最后,我使用@Lazy对服务(使用@Async注释的方法),以及进行了整理,在这些服务中进行了自动装配。 这种方式我认为Spring仅在需要时初始化并自动装配这些服务,而不是应用程序上下文初始化。

答案 1 :(得分:2)

我遇到了同样的问题,并且解决了这个问题:

  1. 我确定了哪个@Autowired属性是循环依赖的原因。

    例如:

    @Autowired
    private TestService testService;
    

    (要标识的提示只是尝试注释并找出是哪个属性导致应用程序中断的原因)

  2. 一旦确定,只需在此@Lazy变量的顶部使用@Autowired

    例如:

    @Lazy
    @Autowired
    private TestService testService;
    

    应用程序运行顺利。

答案 2 :(得分:0)

我设法通过将@Qualifier与@Autowire一起添加来解决类似的问题,例如:

@Autowired
@Qualifier("publisher")
private Publisher publisher;

答案 3 :(得分:0)

AsyncConfigurer 配置类会在应用程序上下文引导中尽早初始化。如果您在那里需要对其他bean的任何依赖,请确保尽可能将它们声明为“惰性”,以使它们也可以通过其他后处理器。

参考JavaDoc:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html