java - Spring中不带@Configuration导入配置类

标签 java spring spring-boot

我不知道它是否受支持,但我不小心@Import'编辑了一个没有@Configuration的Spring配置。结果,我得到了一个神秘的循环依赖错误,显然不是这样的(或者至少我无法识别它)。这是错误消息,我并没有真正理解:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanC' defined in URL[jar:file:/Users/ghornyak/work/dev/sandbox/spring-boot-tutorial/build/libs/gs-spring-boot-0.1.0.jar!/BOOT-INF/classes!/hello/BeanC.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hello.config.TestConfig': Unsatisfied dependency expressed through method 'beanB' parameter 0; nested exception is
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?

这是一个简化的示例:BeanBBeanC 都依赖于 BeanABeanA BeanB 是在 TestConfig 类中定义的,缺少 @Configuration 注释。

配置来源:

package hello.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

import hello.BeanA;
import hello.BeanB;

public class TestConfig {

    @Bean
    public BeanA beanA() {
        System.out.println("Creating beanA");
        return new BeanA();
    }

    @Bean
    @Autowired
    public BeanB beanB(BeanA beanA) {
        System.out.println("Creating beanB: " + beanA);
        return new BeanB();
    }
}

BeanC的定义:

package hello;

import org.springframework.stereotype.Component;

@Component
public class BeanC {

    public BeanC(BeanA beanA) {
        System.out.println("Creating BeanC: " + beanA);
    }
}

测试应用程序:

package hello;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

import hello.config.TestConfig;

@SpringBootApplication
@Import(TestConfig.class)
@ComponentScan(basePackageClasses = Application.class)
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

现在,如果我使用 @Configuration 注释标记配置,错误就会消失,一切都会按预期工作。

那么问题来了,导入的配置类上应该有前面提到的注解吗?如果是这样,那么为什么没有显示错误呢?

最佳答案

是的,这是预期的,你不能在同一个类中的另一个bean定义中调用bean,除非你用@Configuration注释该类,这背后的原因是cglib创建了spring需要引用和调用bean的AOP代理

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original 'Spring JavaConfig' project which require CGLIB subclassing of each such configuration class at runtime. As a consequence, @Configuration classes and their factory methods must not be marked as final or private in this mode

检查这个link

关于java - Spring中不带@Configuration导入配置类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47891855/

相关文章:

java - 如何检查ImageInputStream是否已经关闭?

java - @ControllerAdvice 不允许显示 Swagger UI

java - 将 apollo 跟踪添加到 GraphQL Spring

java - 让一个 Spring bean 继承另一个 Spring bean 是一种好的做法吗?

java - Android 版 Google map - 检查您以前是否来过这里

java - 反向比较回文解(破解编码面试)

java - 当类实现 Callable 接口(interface)时 Spring Env 为 null

Java Spring Boot Hibernate、JPA、MVC、REST混淆

java - Spring Boot war 无法在 Resin 服务器上正确部署

java - 动态调度任务的异步执行