spring 自动装配 aop 循环依赖
spring autowired aop circular dependency
我使用 java 配置和 @ComponentScan
来初始化我的 beans
@EnableAspectJAutoProxy(proxyTargetClass=true)
使用 cglib 代理。
在这个项目中,我们使用 @Autowired
在它们之间自动装配了许多生成的服务。效果很好。
但是,对于其中一些服务,我添加了 @Async
(我还在 @Configuration
class 中添加了 @EnableAsync(proxyTargetClass = true)
)。
在那之后,我得到:
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 在 AOP 创建代理之前使用 @Async
方法注入服务。
这可能是问题所在吗?
我该如何解决?
为了澄清我的问题,假设我有:
@服务 A、B 和 C;
A 已自动装配 B 和 C,B 已自动装配 A 和 C,C 已自动装配 A 和 B;
C 有一个标记为@Async 的方法。
当Spring初始化applicationContext时,它尝试初始化A,但需要B和C,所以它初始化它们。但毕竟,AOP 尝试创建 C 的代理(因为 @Async),然后它检测到自动装配到 B 和 A 的 C 与 C 的代理不同,因此它失败了。
我希望这可以解释更多正在发生的事情。
最后,我使用 @Lazy
on 服务(使用 @Async
注释的方法)、 和 对其进行了整理,其中它们是自动装配的。
这样我猜 Spring 只在需要时初始化和自动连接这些服务,而不是在应用程序上下文初始化时。
我通过添加@Qualifier 和@Autowire 设法解决了类似的问题,例如:
@Autowired
@Qualifier("publisher")
private Publisher publisher;
AsyncConfigurer 配置 类 在应用程序上下文中提前初始化 bootstrap。如果您需要对其他 beans 的任何依赖,请确保尽可能地声明它们 @Lazy
,以便让它们也通过其他 post-processors。
我有同样的问题,我解决了这个问题:
我确定了哪个 @Autowired
属性 是循环依赖的原因。
例如:
@Autowired
private TestService testService;
(识别的提示只是尝试评论并找出哪个 属性 是破坏应用程序的原因)
一旦确定,只需在此 @Autowired
变量之上使用 @Lazy
。
例如:
@Lazy
@Autowired
private TestService testService;
并且应用程序运行顺利。
我使用 java 配置和 @ComponentScan
来初始化我的 beans
@EnableAspectJAutoProxy(proxyTargetClass=true)
使用 cglib 代理。
在这个项目中,我们使用 @Autowired
在它们之间自动装配了许多生成的服务。效果很好。
但是,对于其中一些服务,我添加了 @Async
(我还在 @Configuration
class 中添加了 @EnableAsync(proxyTargetClass = true)
)。
在那之后,我得到:
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 在 AOP 创建代理之前使用 @Async
方法注入服务。
这可能是问题所在吗?
我该如何解决?
为了澄清我的问题,假设我有:
@服务 A、B 和 C;
A 已自动装配 B 和 C,B 已自动装配 A 和 C,C 已自动装配 A 和 B;
C 有一个标记为@Async 的方法。
当Spring初始化applicationContext时,它尝试初始化A,但需要B和C,所以它初始化它们。但毕竟,AOP 尝试创建 C 的代理(因为 @Async),然后它检测到自动装配到 B 和 A 的 C 与 C 的代理不同,因此它失败了。
我希望这可以解释更多正在发生的事情。
最后,我使用 @Lazy
on 服务(使用 @Async
注释的方法)、 和 对其进行了整理,其中它们是自动装配的。
这样我猜 Spring 只在需要时初始化和自动连接这些服务,而不是在应用程序上下文初始化时。
我通过添加@Qualifier 和@Autowire 设法解决了类似的问题,例如:
@Autowired
@Qualifier("publisher")
private Publisher publisher;
AsyncConfigurer 配置 类 在应用程序上下文中提前初始化 bootstrap。如果您需要对其他 beans 的任何依赖,请确保尽可能地声明它们 @Lazy
,以便让它们也通过其他 post-processors。
我有同样的问题,我解决了这个问题:
我确定了哪个
@Autowired
属性 是循环依赖的原因。例如:
@Autowired private TestService testService;
(识别的提示只是尝试评论并找出哪个 属性 是破坏应用程序的原因)
一旦确定,只需在此
@Autowired
变量之上使用@Lazy
。例如:
@Lazy @Autowired private TestService testService;
并且应用程序运行顺利。