基本概念:@Bean@Configuration

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

@Bean注解用于指示一个方法实例化、配置和初始化一个新的对象,由Spring IoC容器管理。对于熟悉Spring的<beans/> XML配置的人来说,@Bean注解的作用与<bean/>元素相同。您可以将@Bean注解的方法与任何Spring @Component一起使用。但是,它们最常与@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>
@Configuration类中是否包含@Bean方法之间的局部调用?

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

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

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

@Bean@Configuration注解将在以下部分详细讨论。但是,首先,我们将介绍使用基于Java的配置创建Spring容器的各种方法。