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();
    }
}

results matching ""

    No results matching ""