首页 > 解决方案 > 使用@Import 注释会创建导入文件中定义的所有bean吗?

问题描述

A.java:

@Configuration
@Import(B.class)
class A {
   @Bean
   public X x(Y y) {
       return new X(y);
   }
}

B.java:

@Configuration
class B {
  @Bean
  public Y y() {
     return new Y();
  }
  // And some other beans are defined
}

B.java实例化bean时是否会实例化所有定义的bean x?由于文件B.java是由A.java.

标签: javaspringspring-bootspring-annotations

解决方案


一个测试:

一个简单的测试来可视化你的答案:

class ATest {
    private static final Logger LOGGER = LoggerFactory.getLogger(A.class);

    private ApplicationContext ctx;

    @BeforeEach
    void setUp() {
        ctx = new AnnotationConfigApplicationContext(A.class);
    }

    @Test
    void test() {
        for (String beanName: ctx.getBeanDefinitionNames()) {
            LOGGER.info("BEAN: " + beanName);
        }
    }
}

输出:

[main] INFO be.dog.d.steven.A - BEAN: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
[main] INFO be.dog.d.steven.A - BEAN: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
[main] INFO be.dog.d.steven.A - BEAN: org.springframework.context.event.internalEventListenerProcessor
[main] INFO be.dog.d.steven.A - BEAN: org.springframework.context.event.internalEventListenerFactory
[main] INFO be.dog.d.steven.A - BEAN: a
[main] INFO be.dog.d.steven.A - BEAN: org.company.B
[main] INFO be.dog.d.steven.A - BEAN: y
[main] INFO be.dog.d.steven.A - BEAN: x

如您所见,@Import确实使应用程序上下文按预期包含了 B 类中的所有 bean。

前 4 个 bean 总是被创建,即使您只使用一个带有注释的空类@Configuration来构建应用程序上下文。将始终创建的第五个 bean 是用于创建上下文的带注释的类。

在实践中:

虽然这很好用,但让您的应用程序@ComponentScan(basePackages = "org.company")在某个包或文件夹中执行操作会更干净。这样,您不必总是向@Import注释中添加新组件。(当您处理一个更大的项目时,您可能也不想扫描整个项目,而只是包含实际组件的文件夹。)

但是,您可以@Import在测试类上使用仅加载该测试的上下文的隔离部分。

您还可以在application.properties中将 Spring Framework 的日志记录级别设置为 DEBUG :

logging.level.org.springframework=DEBUG

通过这种方式,您还可以检查应用程序的日志以查看创建了哪些 bean。


推荐阅读