Spring 新的 Java 配置支持的核心工件是 @Configuration 注解类和 @Bean 注解方法。

@Bean 注解用来表示一个方法实例化、配置和初始化了一个新的对象,由 Spring IoC 容器管理。对于那些熟悉 Spring 的 <beans/> XML 配置的人来说,@Bean 注解的作用与 <bean/>元素的作用相同。你可以在任何 Spring @Component中使用 @Bean注解的方法。然而,它们最常被用于@Configuration Bean。

@Configuration来注解一个类,表明它的主要目的是作为 Bean 定义的来源。此外,@Configuration类允许通过 调用 同一个类中的其他 @Bean方法来定义 Bean 间的依赖关系。最简单的 @Configuration类如下:

  1. @Configuration
  2. public class AppConfig {
  3. @Bean
  4. public MyService myService() {
  5. return new MyServiceImpl();
  6. }
  7. }

前面的 AppConfig 类等价于下面的 Spring < beans/> XML:

  1. <beans>
  2. <bean id="myService" class="com.acme.services.MyServiceImpl"/>
  3. </beans>

完整的 @Configuration 与 「精简的」@Bean 模式?

当 @Bean 方法被声明在没有 @Configuration 注解的类中时,它们被称为以 「精简 」模式处理。在@Component 或甚至在一个普通的类中声明的 Bean 方法被认为是 「精简 」的,包含类的主要目的不同,而 @Bean 方法是那里的一种奖励。例如,服务组件可以通过每个适用的组件类上的一个额外的@Bean 方法向容器暴露管理视图。在这种情况下,@Bean 方法是一种通用的工厂方法机制。

与完整的 @Configuration 不同,精简的 @Bean 方法不能声明 Bean 之间的依赖关系。相反,它们对其包含的组件的内部状态进行操作,也可以选择对其可能声明的参数进行操作。因此,这样的 @Bean 方法不应该调用其他的 @Bean 方法。每个这样的方法从字面上看只是一个特定的 Bean 引用的工厂方法,没有任何特殊的运行时语义。这里积极的副作用是,在运行时不需要应用 CGLIB 子类,所以在类的设计方面没有任何限制(也就是说,包含类可以是 final 的等等)。

在常见的情况下,@Bean 方法要在 @Configuration 类中声明,确保始终使用 「完整 」模式,因此跨方法引用会被重定向到容器的生命周期管理。这可以防止同一个 @Bean 方法被意外地通过普通的 Java 调用来调用,这有助于减少在 「精简 」模式下操作时很难追踪到的细微 Bug。

下面几节将深入讨论 @Bean 和 @Configuration 注解。然而,首先,我们将介绍通过使用基于 Java 的配置来创建 spring 容器的各种方法。