简体   繁体   English

使用@Import 注释是否会创建导入文件中定义的所有 bean?

[英]Does using @Import annotation create all beans defined in imported file?

A.java: A.java:

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

B.java: B.java:

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

Will all beans defined in B.java be instantiated when bean x is instantiated?当bean x被实例化时, B.java定义的所有bean B.java被实例化吗? Since the file B.java is imported by A.java .由于文件B.java是由A.java导入的。

A Test:一个测试:

A simple test to visualize your answer:一个简单的测试来可视化你的答案:

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);
        }
    }
}

Output:输出:

[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

As you can see, @Import did make the application context include all beans in class B as expected.如您所见, @Import确实使应用程序上下文按预期包含类 B 中的所有 bean。

The first 4 beans are always created, even if you use just one empty class annotated with @Configuration to build the application context.前 4 个 bean 始终被创建,即使您只使用一个用@Configuration注释的空类来构建应用程序上下文。 The fifth bean that will always be created is the annotated class used to create the context.将始终创建的第五个 bean 是用于创建上下文的带注释的类。

In practice:在实践中:

Although this works fine, it is cleaner to have your application do a @ComponentScan(basePackages = "org.company") in a certain package or folder.尽管这工作正常,但让您的应用程序在某个包或文件夹中执行@ComponentScan(basePackages = "org.company")会更清晰。 This way you do not always have to add new components to the @Import annotation.这样您就不必总是向@Import注释添加新组件。 (You might also not want to scan the whole project when you are working on a bigger project, rather just folders containing actual components.) (在处理更大的项目时,您可能也不想扫描整个项目,而只想扫描包含实际组件的文件夹。)

You can however use @Import on test classes to only load an isolated part of the context for that test.但是,您可以在测试类上使用@Import来仅为该测试加载上下文的隔离部分。

You can also set the logging level of the Spring Framework to DEBUG in the application.properties :您还可以在application.properties中将 Spring Framework 的日志记录级别设置为 DEBUG:

logging.level.org.springframework=DEBUG

This way you can also check the logs of your application to see what beans get created.通过这种方式,您还可以检查应用程序的日志以查看创建了哪些 bean。

First I ran the sample that is posted by you.首先,我运行了您发布的示例。 Then I tested one sample with following variation,然后我测试了一个具有以下变化的样本,

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

And then the last variation as following,然后最后的变化如下,

@Slf4j
@Configuration
class B {
    @Bean
    public Y y() {
        log.info("Creating bean Y in B {}", System.currentTimeMillis());
        return new Y();
    }

    @Bean
    public Z z(){
        log.info("Creating bean Z in B {}", System.currentTimeMillis());
        return new Z();
    }
    // And some other beans are defined
}

Here is what I inferred from my observations,这是我从我的观察中推断出来的,

  • A bean is always when you're using the annotation @Bean , bean is declared from a class which is annotated with either @Component , @Configuration or @Service and your component class is part of your declared package in @ComponentScan , then Spring will always register your bean.当您使用注解@Bean ,bean 始终是从类中声明的,该类使用@Service Component、 @Service @Configuration@Service进行@Component ,并且您的组件类是您在@ComponentScan声明的包的一部分,然后 Spring 将总是注册你的bean。 I can safely say that @Import has very little to do with bean creation.我可以肯定地说,@Import 与 bean 的创建关系不大。
  • Upon running second first(one with default constructor) multiple times, I found bean X created before bean Y.在多次运行第二个(带有默认构造函数的)时,我发现在 bean Y 之前创建了 bean X。
  • Upon running second variation where I declared more than one bean in class B, the order of bean creation was Y, X and then Z.在运行我在 B 类中声明多个 bean 的第二个变体时,bean 创建的顺序是 Y、X 和 Z。

@Import is just used to group your bean definition source as I found here on Baeldung, @Import @Import 只是用来对你的 bean 定义源进行分组,正如我在 Baeldung 上找到的那样, @ Import

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 查找所有具有自定义注释的bean,并从此bean创建解析器 - Find all beans with custom annotation and create resolver from this beans 在Sqoop文件导入中,我想使用定义的映射器控制文件拆分中的导入数据 - In Sqoop, file import, I would like to control the imported data within file splits using defined mappers 使用特定注释注入所有bean - Inject all beans with a specific annotation 是否可以在同一个Java Web应用程序中使用xml创建一些bean,并使用基于注释的方法创建其余bean? - Is it possible to create some beans using xml and the remaining beans using annotation based approach in the same java web application 使用 Net Beans 创建 JAR 文件,包括所有依赖的库和文件夹 - Create JAR file using Net Beans including all dependent libs and folders 如何获取所有具有@Entity 注释的bean? - How to get all beans that have @Entity annotation? 为什么Spring Boot不使用任何@Primary注释就创建相同类型的bean? - Why does Spring Boot create beans of the same type regardless of any @Primary annotation? 使用Spring @Configuration批注注入bean列表 - Inject a list of beans using Spring @Configuration annotation 使用注释配置bean的Spring安全配置 - Spring security configuration using annotation configured beans 使用注解配置引用多个 bean - Refering multiple beans using annotation configuration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM