Spring之@Bean注解详解

  • Post author:
  • Post category:其他




@Bean总体介绍

此注释的属性的名称和语义有意地与springxml模式中的元素的名称和语义相似。

Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。

SpringIOC 容器管理一个或者多个bean,这些bean都需要在@Configuration注解下进行创建,在一个方法上使用@Bean注解就表明这个方法需要交给Spring进行管理。


与@Configuration配合使用


通常,@Bean方法在@Configuration类中声明。在这种情况下,bean方法可以通过直接调用同一类中的其他@bean方法来引用它们。这确保了bean之间的引用是强类型的和可导航的。


lite模式


@Bean方法也可以在没有@Configuration注释的类中声明。例如,bean方法可以在@Component类中声明,甚至可以在普通的旧类中声明。在这种情况下,@Bean方法将以所谓的“lite”模式进行处理。

lite模式下的Bean方法将被容器视为普通工厂方法(类似于XML中的工厂方法声明 factory-method属性),并正确应用范围和生命周期回调。

与@Configuration classes中bean方法的语义不同,lite模式不支持“bean间引用”。相反,当一个@Bean方法以lite模式调用另一个@Bean方法时,调用是一个标准的Java方法调用;

必须特别考虑返回spring beanfactorypostprocessor(BFPP)类型的@Bean方法。由于BFPP对象必须在容器生命周期的早期实例化(前面博客讲过,在实例化对象之前执行BFPP),因此它们可能会干扰@Configuration类中的@Autowired、@Value和@PostConstruct等注释的处理。为了避免这些生命周期问题,将返回@Bean方法的BFPP标记为static。例如:

@Bean
       public static PropertySourcesPlaceholderConfigurer pspc() {
           // instantiate, configure and return pspc ...
       }

通过将此方法标记为static,可以调用它,而无需实例化其声明的@Configuration类,从而避免上述生命周期冲突。但是请注意,静态@Bean方法不会像上面提到的那样为作用域和AOP语义增强。这在BFPP情况下是可行的,因为它们通常不会被其他@Bean方法引用。作为提醒,对于返回类型可分配给BeanFactoryPostProcessor的任何非静态@Bean方法,都将发出警告级别日志消息。

对上面一段做出一个解释:

如果是一个beanfactorypostprocessor类型的类,用@Bean加入Spring容器的话(通常使用@Component加入Spring容器),因为beanfactorypostprocessor类是在大部分对象实例化开始之前去进行实例化的,所以在实例化该类时,会影响到@Autowired、@Value和@PostConstruct的处理。具体怎么影响的我们讲到这几个注解时再讲解。下面我们做个试验:

@Configuration
public class BeanTest {

    /**
     * 自定义类
     * @return
     */
    @Bean
    public  Cs getCs(){
        System.out.println("初始化完成CS");
        return  new Cs("1","测试");
    }

    /**
     * BeanFactoryPostProcessor类
     * @return
     */
    @Bean
    public  MyBeanFactoryPostProcessor getCC(){
        System.out.println("初始化完成后置处理器");
      return  new MyBeanFactoryPostProcessor();
    }
}

启动项目,项目日志中会提示这条日志:

@Bean method BeanTest.getCC is non-static and returns an object assignable to Spring’s BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method’s declaring @Configuration class. Add the ‘static’ modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.

@Bean方法BeanTest.getCC是非静态的,返回可分配给Spring的BeanFactoryPostProcessor接口的对象。这将导致无法在方法的声明@Configuration类中处理注释,例如@Autowired、@Resource和@PostConstruct。

当我们把返回MyBeanFactoryPostProcessor对象的方法改为static时,就没有这个报错了。所以,当我们采用@Bean返回BeanFactoryPostProcessor对象时,最好加上static。




@Bean属性介绍


value

: name属性的别名,在不需要其他属性时使用,也就是说value 就是默认值。


name

: 此bean 的名称,或多个名称,主要的bean的名称加别名。如果未指定,则bean的名称是带注解方法的名称。如果指定了,方法的名称就会忽略,如果没有其他属性声明的话,bean的名称和别名可能通过value属性配置


autowire

:等同于xml中bean的autowire熟悉,不推荐使用此属性。


autowireCandidate

:等同于xml中bean标签的autowire-candidate属性。


initMethod

:在初始化期间对bean实例调用的方法的可选名称。不常用,因为该方法可以直接在Bean注释方法的主体中以编程方式调用。等同于xml bean标签中的init-method属性。


destroyMethod

:等同于xml bean中的destory方法。



版权声明:本文为qq1309664161原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。