7.12.3 Using the @Bean annotation
@Bean是一个方法级别的注解与XML中的<bean/>元素类似。该注解支持<bean/>元素提供的属性,例如:init-method, destroy-method, autowiring 和 name.
你可以在@Configuration和@Component标注的类下使用该注解
定义一个bean
声明一个bean,仅仅需要在相应的方法上添加@Bean注解。方法的返回类型就是这个bean的类型,默认的bean的名字就是方法的名字,下面是一个简单的@bean方法的示例
@Configuration
public class Appconfig{
@Bean
public TransferService transferService(){
return new TransferServiceImpl();
}
}
上述的配置与下面的XML配置一样
<beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
两个声明使一个类型为TransferServiceImpl名称为transferSerive的bean的在ApplicationContext中可用。
transferService -> com.acme.TransferServiceImpl
Bean的依赖
一个被@Bean标注的方法可能有多个可变的参数来描述构建这个bean所需要的依赖。如如果我们TransferService需要一个AccountRepository我们可以通过方法参数实例化这个对象
@Configuration
public class AppConfig{
@Bean
public TransferService transferService(AccountRepository accountRepository){
return new TransferServiceImpl(accountRepository);
}
}
接受生命周期的回调
一个@Bean定义的类支持正常的生命周期的回调并且可以使用@PostConstruct和@PreDestory
也全部支持Spring正常的生命周期的回调。如果一个bean实现了InitializingBean, DisposableBean或Lifecycle,他们代表的方法将会被容器调用
标准的*Aware系列接口如BeanFactoryAware, BeanNameAware, MessageSourceAware, ApplicationContextAware都全部支持。
@Bean注解支持指定的可变的初始化和销毁方法,跟Spring XML bean的init-method和destory-method属性非常相似
public class Foo{
public void init(){
}
}
public class Bar{
public void cleanup(){
}
}
@Configuration
public class AppConfig{
@Bean(initMethod="init")
public Foo foo(){
return new Foo();
}
@Bean(destroyMethod="cleanup")
public Bar bar(){
return new Bar();
}
}
默认的,使用Java配置的beans如果有close或shutdown方法,当容器销毁时会自动调用该方法(close的优先级大于shutdown)。如果你的类里有一个公开的close或shutdown方法而在容器关闭时不想被调用,可添加@Bean(destroyMethod="")对你定义的bean上来禁止默认的(inferred)模式
当然上面Foo定义的情况,等价于在构造时调用init()方法
@Configuration
public class AppConfig{
@Bean
public Foo foo(){
Foo foo = new Foo();
foo.init();
return foo;
}
}
指定bean的作用域
使用@Scope注解
在使用@bean定义定义bean的时候,你可以指定作用域。你可以使用任何在Bean scopes章节介绍的作用域
默认的作用域是singleton,但你可以使用@Scope注解覆盖掉他
@Configuration
public class MyConfiguration{
@Bean
@Scope("prototype")
public Encryptor encryptor(){
//...
}
}
@Scope和scoped-proxy
@SessionScope
@RequestScope
自定义bean的名称
默认的情况下,配制类使用@Bean方法的名子作为bean的name.这个功能可以被覆盖,指定name属性
@Configuration
public class AppConfig{
@Bean(name="myFoo")
public Foo foo(){
return new Foo();
}
}
Bean的别名
@Bean的name属性可以接收一个字符数组,这样就可以为一个bean提供多个别名
@Configuration
public class AppConfig{
@Bean(name = {"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
public DataSource dataSource(){
}
}
Bean的描述
一些时候给一个bean提供一些详细的描述文本信息是很有用的。
@Configuration
public class AppConfig{
@Bean
@Description("Provides a basic example of a bean")
public Foo foo(){
return new Foo();
}
}