java - @Repository 类中的自引用导致循环引用
问题描述
我发现自我引用@Repository
不起作用,例如:
@Repository
public class HelloService {
static final Logger Log = LoggerFactory.getLogger(HelloService.class);
@Autowired
HelloService self; // <----- self reference
...
}
得到循环引用错误
osbwscAnnotationConfigServletWebServerApplicationContext - 上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.BeanCurrentlyInCreationException:创建名称为“helloService”的bean时出错:名称为“helloService”的bean已被注入原始版本中的其他bean [helloService]作为循环引用的一部分,但最终被包装了。这意味着所说的其他 bean 不使用 bean 的最终版本。这通常是过度渴望类型匹配的结果 - 例如,考虑使用 'getBeanNamesOfType' 并关闭 'allowEagerInit' 标志。
Repository
但是,当更改为@Component
or时,此技巧可能会起作用@Service
。作为一种解决方法,我必须@Lazy
在self
.
解决方案
您的行为HelloService
取决于您的 Spring Data JPA 存储库是如何被引导的,在这种情况下,这似乎是默认模式:
- DEFAULT(默认)- 除非使用 @Lazy 显式注释,否则存储库会被急切地实例化。
阅读日志,并查找此条目:
RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in XYZ mode.
然后看看那个XYZ是什么。
@Lazy
帮助你,因为:
如果 @Component 或 @Bean 定义上不存在此注解,则会发生急切初始化。如果存在并设置为 true,则 @Bean 或 @Component 在被另一个 bean 引用或从封闭的 BeanFactory 显式检索之前不会被初始化。
为了了解您的其他组件是如何被初始化的,最好有日志、属性、配置或其他任何可能影响 Spring 应用程序行为的东西。如果您不提供最小的可重现示例,真的很难猜出您拥有什么
其他要点:
A
通常,注入是一种非常糟糕的做法A
,而且您几乎应该永远不要这样做。
但是,如果没有将@Lazy
beanA
注入到自身中,那么您将得到异常也就不足为奇了。你需要在 Spring Container 中有一个现成的 bean,以便将它注入某个地方;而且,为了准备好那个 bean,Spring 必须注入它的依赖项.. 然而,在你的代码中:
@Repository
public class HelloService {
static final Logger Log = LoggerFactory.getLogger(HelloService.class);
@Autowired
HelloService self; // <----- self reference
...
}
这取决于它自己。
您要告诉应用程序上下文:
- 实例化 bean
helloService
(包括准备它,通过注入它的每个依赖项); helloService
将bean注入自身。
你认为step 2
不先完成就可以完成step 1
吗?step 1
如果step 2
无法完成,将如何完成?
您正在注入尚未准备好的东西,为了准备好,您需要注入它本身,这又是未准备好......等等......
这会让你遇到循环引用问题,这是一个死锁。
推荐阅读
- fortran - 使用 if 条件将数组中的负值设置为零
- java - 无法从蓝牙耳机接收 AT 命令
- jboss - 如何在 JBOSS EAP 7.1 中禁用 http-header “xpowered-by / server”?
- xamarin - 如何修改特定的 ListView 项目以回发到 db - MVVM
- java - 具有 ConcurrentHashmap 策略的 Java 多线程使用者
- python - 将 JSON 响应转换为 python 对象
- jestjs - Jest + Material-UI:正确模拟 useMediaQuery
- reactjs - 在Formik中提交后如何重置/清空表单
- angular - Angular 自定义装饰器 - 使用服务
- powershell - 哪里可以得到 Powershell 的 PKI 模块