跳到主要内容

基本概念:@Bean@Configuration

DeepSeek V3 中英对照 Basic Concepts: @Bean and @Configuration Basic Concepts: @Bean and @Configuration

Spring 的 Java 配置支持中的核心构件是带有 @Configuration 注解的类和带有 @Bean 注解的方法。

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

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

@Configuration
public class AppConfig {

@Bean
public MyServiceImpl myService() {
return new MyServiceImpl();
}
}
java

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

<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
xml

@Bean 方法之间是否有本地调用的 @Configuration 类?

在常见场景中,@Bean 方法应声明在 @Configuration 类中,以确保完整的配置类处理得以应用,并且跨方法引用因此被重定向到容器的生命周期管理。这可以防止通过常规的 Java 方法调用意外地调用相同的 @Bean 方法,从而有助于减少那些难以追踪的微妙错误。

@Bean 方法声明在未使用 @Configuration 注解的类中,或者声明了 @Configuration(proxyBeanMethods=false) 时,它们被称为以“轻量”模式处理。在这种情况下,@Bean 方法实际上是一种通用的工厂方法机制,没有特殊的运行时处理(即不会为其生成 CGLIB 子类)。对此类方法的自定义 Java 调用不会被容器拦截,因此其行为与常规方法调用相同,每次都会创建一个新实例,而不是重用给定 bean 的现有单例(或作用域)实例。

因此,在没有运行时代理的类上的 @Bean 方法根本不意味着声明 bean 之间的依赖关系。相反,它们应该操作其包含组件的字段,并且可以选择性地操作工厂方法可能声明的参数,以便接收自动装配的协作者。因此,这样的 @Bean 方法永远不需要调用其他 @Bean 方法;每个这样的调用都可以通过工厂方法参数来表达。这里的积极副作用是,在运行时不需要应用 CGLIB 子类化,从而减少了开销和内存占用。

@Bean@Configuration 注解将在后续章节中深入讨论。然而,首先我们将介绍通过基于 Java 的配置来创建 Spring 容器的各种方法。