首页 > 解决方案 > @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但是,当更改为@Componentor时,此技巧可能会起作用@Service。作为一种解决方法,我必须@Lazyself.

标签: javaspring

解决方案


您的行为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,而且您几乎应该永远不要这样做。

但是,如果没有将@LazybeanA注入到自身中,那么您将得到异常也就不足为奇了。你需要在 Spring Container 中有一个现成的 bean,以便将它注入某个地方;而且,为了准备好那个 bean,Spring 必须注入它的依赖项.. 然而,在你的代码中:

@Repository
public class HelloService {
    static final Logger Log = LoggerFactory.getLogger(HelloService.class);

    @Autowired
    HelloService self;  // <----- self reference
    ...
}

这取决于它自己。

您要告诉应用程序上下文:

  1. 实例化 bean helloService(包括准备它,通过注入它的每个依赖项);
  2. helloService将bean注入自身。

你认为step 2不先完成就可以完成step 1吗?step 1如果step 2无法完成,将如何完成?

您正在注入尚未准备好的东西,为了准备好,您需要注入它本身,这又是未准备好......等等......

这会让你遇到循环引用问题,这是一个死锁。


推荐阅读