Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧圆形参考示例_Java_Spring_Dependency Injection_Autowired_Circular Reference - Fatal编程技术网

Java 弹簧圆形参考示例

Java 弹簧圆形参考示例,java,spring,dependency-injection,autowired,circular-reference,Java,Spring,Dependency Injection,Autowired,Circular Reference,在使用spring的一个项目中,我有一个循环引用,我无法修复该引用,启动时出现以下错误: 'org.springframework.security.authenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference? 我在一个示例项目中尝试在较小的层次上重新创建相同的问题(没有我工作项目的所有细节)。然而,我无法提出一个合理的场景,即sprin

在使用spring的一个项目中,我有一个循环引用,我无法修复该引用,启动时出现以下错误:

'org.springframework.security.authenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference?
我在一个示例项目中尝试在较小的层次上重新创建相同的问题(没有我工作项目的所有细节)。然而,我无法提出一个合理的场景,即spring因错误而失败。 以下是我所拥有的:

public class ClassA {
    @Autowired
    ClassB classB;
}

public class ClassB {
    @Autowired
    ClassC classC;
}

@Component
public class ClassC {
    @Autowired
    ClassA classA;
}

@Configuration
public class Config {
    @Bean
    public ClassA classA() {
        return new ClassA();
    }

    @Bean
    public ClassB classB() {
        return new ClassB();
    }
}
我的项目中有一个类似的场景,失败了,我希望spring也会在我的示例项目中抱怨。但是它很好用!有人能给我一个简单的例子,如何打破弹簧的圆形参考误差


编辑:我使用javax.inject.Provider解决了这个问题。这两个项目中唯一的区别是使用的注释是javax.inject.inject和javax.annotation.ManagedBean,而不是@Autowired和@Component。

您可以使用
@Lazy
来指示bean是惰性创建的,从而打破了自动连接的急迫循环

其思想是,可以将循环中的某些bean实例化为代理,并在真正需要它的时候对其进行初始化。这意味着,除了作为代理的bean之外,所有bean都被初始化。第一次使用它将触发配置,因为其他bean已经配置好了,所以不会有问题

摘自《春吉拉》的一期:

@可与@Configuration一起使用的惰性注释 指示该配置类中的所有bean都应 懒散地初始化。当然,@Lazy也可以结合使用 使用单个@Bean方法来指示 一个接一个。

这意味着将bean注释为
@Lazy
就足够了。或者,如果您愿意,只需将配置类注释为
@Lazy
,如下所示:

@Configuration
@Lazy
public class Config {
    @Bean
    public ClassA classA() {
        return new ClassA();
    }

    @Bean
    public ClassB classB() {
        return new ClassB();
    }
}

如果您实现了bean的接口,这将非常有效。

根据Spring文档,通过使用构造函数注入可以获得循环依赖性问题或
beancurrentlyIncrementationException

解决这个问题的方法是使用setter而不是构造函数注入


参考资料。

这是一条老线索,所以我想你几乎忘记了这个问题,但我想让你知道这个秘密。我遇到了同样的问题,我的问题并没有神奇地消失,所以我必须解决这个问题。我会一步一步地解决你的问题

1。为什么无法复制循环引用异常?

因为

2。那么为什么您的项目会产生异常?

  • 正如@sperumal所说,如果使用构造函数注入,Spring可能会产生循环异常
  • 根据日志,您在项目中使用Spring安全性
  • 在Spring安全配置中,它们确实使用构造函数注入
  • 注入
    authenticationManager
    的bean具有循环引用
3。那么为什么异常会神秘地消失呢?

异常是否发生取决于bean的创建顺序。我猜您制作了几个
*context.xml
文件,并在web.xml中使用下面类似的配置加载它们

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:*-context.xml</param-value>
</context-param>

上下文配置位置
类路径:*-context.xml
xml文件将由
XmlWebApplicationContext
类加载,文件的加载顺序不保证。它只是从文件系统加载文件。问题就在这里。如果该类首先加载应用程序上下文文件,则没有问题,因为当您的bean用于Spring安全性的构造注入时,它们已经被创建。但是,如果它首先加载Spring安全上下文文件,就会出现循环引用问题,因为Spring会在创建bean之前尝试在构造函数注入中使用bean

4。如何解决问题?


强制xml文件的加载顺序。在本例中,我使用
在应用程序上下文文件的末尾加载了安全上下文xml文件。即使使用相同的代码,加载顺序也可以根据环境进行更改,因此我建议设置加载顺序以消除潜在问题。

我认为您误解了其中的内容:如果您主要使用构造函数注入,可以创建无法解决的循环依赖场景。构造函数注入优于setter注入-直到构造函数调用完成,您的bean才存在,使用setter注入时,您可能会忽略一些必要的参数,并且bean会在未正确配置的状态下存在一段时间,这只是为了补充一点,我们遇到了一个类似的问题(使用SpringTemplateEngine的注入)。“setter注入”解决方案没有帮助,但是
@Lazy
注释起到了作用。感觉就像是一个创伤性的创可贴,但现在我要赢得胜利,然后走开。谢谢你,斯佩斯先生。