java 当@Autowired和@Bean出现在同一个类中时出现BeanCurrentlyInCreationException异常

iezvtpos  于 2022-12-25  发布在  Java
关注(0)|答案(2)|浏览(161)
@Configuration
public class Test1 {

    @Autowired
    private Test3 test3;

}

@Configuration
public class Test2 {

    @Autowired
    private Test3 test3;

    @Bean(name = "test3 ")
    Test3 test3 () {
        return new Test3(); 
    }
}

上面的代码给出了以下错误。
导致原因:组织。springframework。bean。工厂。bean创建异常:创建名为"test1"的Bean时出错:自动连接依赖项的注入失败;嵌套的异常是org. springframework. bean.工厂。无法自动连接字段:私有测试3 com.package.name.test1.test3;
嵌套的异常是org. springframework. bean.工厂。创建名为"test2"的Bean时出错:自动连接依赖项的注入失败;嵌套的异常是org. springframework. bean.工厂。无法自动连接字段:私有测试3 com.package.name.Test2.test3;
嵌套异常是org.springframework.beans.factory。当前创建中的bean异常:创建名为"test3"的Bean时出错:当前正在创建请求的Bean:是否存在无法解析的循环引用?
这是一个循环依赖的例子吗?如果是,有什么解决这个问题的想法吗?

wswtfjt7

wswtfjt71#

您不需要自动连接在同一个类中定义的bean,因为您可以通过调用初始化方法test 3()直接引用该bean。

@Configuration
public class Test2{

    @Bean(name = "test3 ")
    Test3 test3 () {
        return new Test3(); 
    }

    public void exampleOfUsingTest3Bean() {
        System.out.println("My test3 bean is" + test3().toString());
    }
}

实际上,你不应该做你想做的事情,因为@Autowired字段是在构造类的时候注入到类中的,而此时不存在名为Test 3的bean,因为它是由正在构造的类的方法定义的。理论上,你可以将这个@Bean方法定义为静态的,它应该可以自动连接,但你不应该这样做。

@Bean(name = "test3 ")
public static Test3 test3 () {
    return new Test3(); 
}
ykejflvf

ykejflvf2#

我不确定这种配置的用例是什么,我通常不在java配置类中使用自动装配。
@Configuration注解类本身就是bean,所以spring创建了一个表示'Test1'的bean ...
所以,按照你的例子:

@Configuration
public class Test1 {

    @Autowired
    private Test3 test3;

}

@Configuration
public class Test2 {

    @Autowired
    private Test3 test3;

    @Bean(name = "test3 ")
    Test3 test3 () {
        return new Test3(); 
    }
}

我将从Test2 bean开始,所以你为Test3创建了一个bean,很好,但是你为什么要把它作为类Test2上的一个数据字段自动连接起来呢?我认为只有一个可能的原因:您有其他bean要使用此Test3 bean。在这种情况下,您可以执行以下操作:

    • 备选案文1**
@Configuration
public class Test2 {

  
    @Bean(name = "test3 ")
    Test3 test3 () {
        return new Test3(); 
    }

    @Bean
    public SomeOtherBean someOtherBean() {
       return new SomeOtherBean(test3()); 
    }

    @Bean
    public YetAnotherBean yetAnotherBean() {
       return new YetAnotherBean(test3()); 
    }
}

注意test3()在这里被调用了两次,但是Test3的同一个示例将被返回(因为Test3是一个单例),这是spring中那些"神奇的"地方之一(从技术上讲,它将@Configuration注解类 Package 到智能代理中,但这超出了问题的范围)。

    • 备选案文2**
@Configuration
public class Test2 {

  
    @Bean(name = "test3 ")
    Test3 test3 () {
        return new Test3(); 
    }

    @Bean
    public SomeOtherBean someOtherBean(Test3 test3) {
       return new SomeOtherBean(test3); 
    }

    @Bean
    public YetAnotherBean yetAnotherBean(Test3 test3) {
       return new YetAnotherBean(test3); 
    }
}

这里,请注意对这些bean的依赖性。
现在,继续讨论Test1:如果你有另一个配置文件(Test)-我再次假设你想把这个Test3 bean注入到这个Test1配置类中定义的bean中。显然前面提到的第一个选项对你来说是不可用的,因为它不会编译,但是你可以很容易地使用第二个选项。
所以,在我个人看来,你不应该把用@Configuration标注的类当作真正的类,而应该把它当作一个非常受限的DSL(碰巧遵循java语法),它允许bean定义。所以,目前在我的项目中,当我处理@Configuration类时,我可能只在测试中使用@Autowired。

相关问题