有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaSpring循环参考示例

在使用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解决了这个问题。注射供应商。这两个项目唯一的区别是使用的注释是javax。注射注入和javax。注释。ManagedBean代替@Autowired和@Component


共 (3) 个答案

  1. # 1 楼答案

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

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

    摘自《春日吉拉》的一期:

    @Lazy annotation that can be used in conjunction with @Configuration to indicate that all beans within that configuration class should be lazily initialized. Of course, @Lazy may also be used in conjunction with individual @Bean methods to indicate lazy initialization on a one-by-one basis. https://jira.springsource.org/browse/SJC-263

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

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

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

  2. # 3 楼答案

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

    1。为什么不能复制循环引用异常

    因为Spring takes care of it. It creates beans and injects them as required

    2。那么为什么你的项目会产生异常呢

    • 正如@sperumal所说,如果使用构造函数注入,Spring可能会产生循环异常
    • 根据日志,您在项目中使用Spring Security
    • 在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>
    

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

    4。如何解决这个问题

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