跳到主要内容
版本:7.0.3

基本概念:@Bean@Configuration

Hunyuan 7b 中英对照 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();
}
}

前面的 AppConfig 类相当于以下 Spring 的 <beans/> XML:

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

@Configuration类中是否可以有或没有@Bean方法之间的本地调用?

在常见的场景中,@Bean方法应该被声明在@Configuration类内部,这样可以确保完整的配置类处理得以应用,同时跨方法的引用也会被重定向到容器的生命周期管理机制上。这样就可以防止通过普通的Java方法调用意外地执行相同的@Bean方法,从而有助于减少那些难以追踪的细微错误。

当@Bean方法被声明在未使用@Configuration注解的类中,或者当声明了@Configuration(proxyBeanMethods=false)时,这些@Bean方法会被以“简化”模式进行处理。在这种情况下,@Bean方法实际上就变成了一种通用工厂方法机制,不会进行特殊的运行时处理(也就是说,不会为其生成CGLIB子类)。对这种方法的自定义Java调用不会被容器拦截,因此其行为就像普通的方法调用一样:每次都会创建一个新的实例,而不会重用现有的单例(或有作用域限制的)实例。

因此,没有运行时代理的类上的@Bean方法根本不应该声明bean之间的依赖关系。相反,它们应该只操作其所在组件的字段,还可以选择性地操作工厂方法可能声明的参数以接收自动注入的协作对象。这样的@Bean方法因此永远不需要调用其他@Bean方法;每次这样的调用都可以通过工厂方法的参数来表达。这样做的一个积极效果是,运行时无需进行CGLIB子类的生成,从而减少了开销和代码体积。

@Bean@Configuration注解在接下来的章节中会有深入的讨论。然而,首先我们会介绍使用基于Java的配置来创建Spring容器的各种方法。