原文 https://www.cnblogs.com/cxuanBlog/p/11179439.html 

 

1.源码

  

/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.core.annotation.AliasFor;


@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

  
    @AliasFor("name")
    String[] value() default {};

    
    @AliasFor("value")
    String[] name() default {};

    @Deprecated
    Autowire autowire() default Autowire.NO;

  
    String initMethod() default "";

  
    String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

}

 

 

2.@Bean 基础声明

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

SpringIOC 容器管理一个或者多个bean,这些bean都需要在@Configuration注解下进行创建

 基础使用实例 

  1)配置类

@Configuration  //表示是个配置类

public class AppConfig {

 

  // 使用@Bean 注解表明myBean需要交给Spring进行管理

  // 未指定bean 的名称,默认采用的bean的名称是 "方法名" 且 "方法名首字母小写"

    @Bean

    public MyBean myBean(){

        return new MyBean();

    }

}

  2)实例pojo类

public class MyBean {

 

    public MyBean(){

        System.out.println("MyBean Initializing");

    }

}

 

  3)使用@bean创建的对象

    1.通过上下文对象获取(AnnotationConfigApplicationContext注释配置应用上下文)

ApplicationContext context = new AnnotationConfigApplicationContext(DruidConfig.class);

Object bean = context.getBean("myBean");

 

    2.@Autowired注入

@Autowired
  private MyBean myBean;

 

 

3.@Bean 构成

3.1注解说明

  1)@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})

    表示不仅可以作用在方法上,也可以作用在注解类型上

  2)@Retention(RetentionPolicy.RUNTIME)

    表示在运行时提供注册。

  3)@Documented 

    表明@Bean注解应该被 javadoc工具记录

3.2属性说明

  1)value name属性的别名,在只需要写一个name属性的时候,可以name=写成value=

  2)name bean 的名称,或多个名称。如果未指定,则bean的名称是带注解方法的名称(首字母小写)

  3)autowire  此注解的方法表示自动装配的类型,返回一个Autowire类型的枚举,我们来看一下Autowire枚举类型的概念

    autowire 枚举确定自动装配状态:即,bean是否应该使用setter注入由Spring容器自动注入其依赖项。// 这是Spring DI的核心概念

public enum Autowire {

  // 常量,表示根本没有自动装配。

NO(AutowireCapableBeanFactory.AUTOWIRE_NO),

// 常量,通过名称进行自动装配

BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),

// 常量,通过类型进行自动装配

BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);

 

private final int value;

Autowire(int value) {

this.value = value;

}

public int value() {

return this.value;

}

public boolean isAutowire() {

return (this == BY_NAME || this == BY_TYPE);

}

}

    @Bean的autowire的默认值为No,默认表示不通过自动装配

  4)initMethod: @Bean注释的方法创建的对象的类里面的初始化方法名

  5)destroyMethod: @Bean注释的方法创建的对象的类里面的销毁方法名

 

  6)initMethod和destroyMethod使用实例

  实例类

public class MyBean {

 

    public MyBean(){

        System.out.println("MyBean Initializing");

    }

 

    public void init(){

        System.out.println("Bean 初始化方法被调用");

    }

 

    public void destroy(){

        System.out.println("Bean 销毁方法被调用");

    }

}

  配置类

@Configurationpublic class AppConfig {

//    @Bean

    @Bean(initMethod = "init", destroyMethod = "destroy")

    public MyBean myBean(){

        return new MyBean();

    }

}

    初始化方法在得到Bean的实例的时候就会被调用,销毁方法在容器销毁或者容器关闭的时候会被调用。

4.@Bean注释的方法带参数时-参数名字问题

如上,有参数masterDataSource。

如果spring容器中只有一个DataSource 类型的bean,那么这里参数的名字可以随意取,spring的这个DataSource 的bean会作为参数传入

如果spring容器有多个DataSource 类型的bean

  那么参数的名字一定要对应bean的名称,这样子才能把这个bean作为参数传入,否则报错。

  或者使用@Qualifier来制定DataSource 的名字@Qualifier("myDatasource")DataSource masterDataSource   myDatasource就是我们要传入的DataSource的Bean的名字