基本概念:@Bean
和 @Configuration
Spring Java 配置支持的核心构件是 @Configuration
注解的类和 @Bean
注解的方法。
@Bean
注解用于指示一个方法实例化、配置并初始化一个新对象,该对象将由 Spring IoC 容器管理。对于熟悉 Spring <beans/>
XML 配置的人来说,@Bean
注解扮演着与 <bean/>
元素相同的角色。你可以在任何 Spring @Component
中使用 @Bean
注解的方法。然而,它们最常与 @Configuration
bean 一起使用。
用 @Configuration
注解一个类表明其主要目的是作为 bean 定义的来源。此外,@Configuration
类允许通过调用同一类中的其他 @Bean
方法来定义 bean 间的依赖关系。最简单的 @Configuration
类如下所示:
-
Java
-
Kotlin
@Configuration
public class AppConfig {
@Bean
public MyServiceImpl myService() {
return new MyServiceImpl();
}
}
@Configuration
class AppConfig {
@Bean
fun myService(): MyServiceImpl {
return MyServiceImpl()
}
}
前面的 AppConfig
类等同于以下 Spring <beans/>
XML:
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
@Bean
方法之间的本地调用?在常见场景中,@Bean
方法应在 @Configuration
类中声明,以确保应用完整的配置类处理,并且跨方法引用因此被重定向到容器的生命周期管理。这可以防止同一个 @Bean
方法通过常规 Java 方法调用意外地被调用,这有助于减少难以追踪的细微错误。当 @Bean
方法在未用 @Configuration
注解的类中声明时,或者当声明了 @Configuration(proxyBeanMethods=false)
时,它们被称为以“lite”模式处理。在这种情况下,@Bean
方法实际上是一种通用的工厂方法机制,没有特殊的运行时处理(即,不为其生成 CGLIB 子类)。对这种方法的自定义 Java 调用不会被容器拦截,因此其行为就像常规方法调用一样,每次都创建一个新实例,而不是重用给定 bean 的现有单例(或作用域)实例。因此,没有运行时代理的类上的 @Bean
方法根本不应声明 bean 间依赖关系。相反,它们应在其包含组件的字段上操作,并且可选地操作工厂方法可能声明的参数以接收自动装配的协作器。因此,这样的 @Bean
方法永远不需要调用其他 @Bean
方法;每个这样的调用都可以通过工厂方法参数来表达。这里的一个积极副作用是,运行时无需应用 CGLIB 子类化,从而减少了开销和占用空间。
@Bean
和 @Configuration
注解将在以下章节中深入讨论。但是,首先,我们将介绍使用基于 Java 的配置创建 Spring 容器的各种方法。