春天自动化了循环依赖

ilo*_*una 25 aop spring spring-java-config spring-aspects

我正在使用java配置@ComponentScan来初始化我的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.
Run Code Online (Sandbox Code Playgroud)

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

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

@Service A,B&C

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

C有一个标记为@Async的方法.

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

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

ilo*_*una 34

最后,我使用@Lazyon服务(使用带注释的方法@Async)对其进行了整理,并且还将它们自动装配.这种方式我猜Spring只是初始化并在需要时自动装配这些服务而不是应用程序上下文初始化.

  • 当Spring创建代理以将异步行为添加到C中时,它不会更新A和B上的引用。因此,它们两个都引用了C的原始版本。 (2认同)

小智 9

我有同样的问题,我解决了这个问题:

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

    例如:

    @Autowired
    private TestService testService;
    
    Run Code Online (Sandbox Code Playgroud)

    (识别提示只是尝试评论并找出哪个属性是破坏应用程序的原因)

  2. 一旦确定,只需@Lazy在此@Autowired变量之上使用。

    例如:

    @Lazy
    @Autowired
    private TestService testService;
    
    Run Code Online (Sandbox Code Playgroud)

    并且应用程序运行顺利。


mas*_*asT 8

AsyncConfigurer配置类在应用程序上下文引导程序的早期初始化。如果您需要对其他 bean 的任何依赖,请确保尽可能地声明它们@Lazy,以便让它们也通过其他后处理器。

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