深入理解spring注解之@Bean注解

@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。添加的bean的id为方法名。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
    @AliasFor("name")
    String[] value() default {};

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

    Autowire autowire() default Autowire.NO;

    String initMethod() default "";

    String destroyMethod() default "(inferred)";
}

value -- bean别名和name是相互依赖关联的,value,name如果都使用的话值必须要一致
name -- bean名称,如果不写会默认为注解的方法名称
autowire -- 自定装配默认是不开启的,建议尽量不要开启,因为自动装配不能装配基本数据类型、字符串、数组等,这是自动装配设计的局限性,以及自动装配不如显示依赖注入精确
initMethod -- bean的初始化之前的执行方法,该参数一般不怎么用,因为可以完全可以在代码中实现
destroyMethod -- bean销毁执行的方法

package net.ydstudio.practise.bean;

import org.springframework.context.annotation.*;

/**
 * 功能描述:<br/>
 * @Bean意思是定义一个bean,该注解是一个方法级别上的注解,可以使用在@Configuration的类里,也可以
 * 在@Component注解的类里,添加的bean的id为方法的名称
 *
 * @Date 2019/4/23 19:36
 */
@Configuration
public class AppConfig {

    /**
     *
     *  下面的代码就相当于在xml之中添加下面的配置
     *  <beans>
     *      <bean id="transferService" class="net.ydstudio.practise.bean.TransferServiceImpl“ ></bean>
     *  </beans>
     *
     *  还能够使用@Scope注解来指定使用@Bean定义的bean
     *  singleton : 单例,整个应用中只存在一个实例bean
     *  prototype : 与单例相对,每次getBean都会重新生成一个Bean。
     *  request : web环境下,每个请求都会创建一个bean,在一次请求中只存在一个Bean,不同request的bean不同
     *  session : web环境下,session生命周期下,获取的是同一个bean
     *
     *  默认情况下,所有单实例bean都会在创建spring容器的时候创建,
     *  如果在bean第一次使用的时候创建,我们称为懒加载
     *  配置很简单,在创建bean的方法上添加@Lazy注解即可
     *
     * @return net.ydstudio.practise.bean.TransferService
     * @date 2019/4/23 19:41
     */
    @Bean
    @Lazy
    @Scope("singleton")
    public TransferService transferService(){
        return new TransferServiceImpl();
    }

    /**
     * @Bean可以依赖其他任意数量的bean,如果TransferService依赖Foo,我们可以通过方法参数实现这个依赖
     *
     * @param: foo
     * @return net.ydstudio.practise.bean.TransferService
     * @date 2019/4/24 11:23
     */
    @Bean
    public TransferService transferService(Foo foo){
        return new TransferServiceImpl(foo);
    }

    /**
     *
     * 任何使用@Bean定义的bean,也可以执行生命周期的回调函数
     * 类似@PostConstruct and @PreDestroy的方法
     *
     * @return net.ydstudio.practise.bean.Foo
     * @date 2019/4/23 19:49
     */
    @Bean(initMethod = "init")
    public Foo foo(){
        return new Foo();
    }

    /**
     * 任何使用@Bean定义的bean,也可以执行生命周期的回调函数
     * 类似@PostConstruct and @PreDestroy的方法
     * @param:
     * @return net.ydstudio.practise.bean.Bar
     * @date 2019/4/23 19:50
     */
    @Bean(destroyMethod = "cleanUp")
    public Bar bar(){
        return new Bar();
    }

    /**
     *
     * 默认情况下bean的名称和方法名称相同,你也可以使用
     * 注解中的name属性进行指定
     *
     * @param:
     * @return net.ydstudio.practise.bean.Foo
     * @date 2019/4/23 19:52
     */
    @Bean(name = "myFoo")
    public Foo getFoo(){
        return new Foo();
    }

    /**
     * 可以通过某些条件,来选择是否注册Bean,通过@Condition注解来实现
     * 实现Condition接口,并重写matches方法,根据该方法返回的布尔值来决定是否注册Bean
     * @return net.ydstudio.practise.bean.Book
     * @date 2019/4/24 11:54
     */
    @Bean
    @Conditional(MyCondition.class)
    public Book book(){
        return new Book();
    }
}
public class Bar {

    public void cleanUp(){
        System.out.println("---111111cleanUp---");
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Bar{");
        sb.append('}');
        return sb.toString();
    }
}

public class Book {
    private String name;
    private BigDecimal price;
    private Date publishDate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Date getPublishDate() {
        return publishDate;
    }

    public void setPublishDate(Date publishDate) {
        this.publishDate = publishDate;
    }
}
public class Foo {
    public void init(){
        System.out.println("初始化之前---init---初始化之前");
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Foo{");
        sb.append('}');
        return sb.toString();
    }
}
public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

        /**
         * 根据环境变量是否存在my.env=hello的属性来决定是否创建,
         * 可以通过启动参数指定-Dmy.env=hello来测试。
         **/
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("my.env");
        if ("hello".equals(property)) {
            return true;
        }
        return false;
    }
}

public interface TransferService {
}
public class TransferServiceImpl implements TransferService{

    private Foo foo;

    public TransferServiceImpl(Foo foo) {
        this.foo = foo;
    }

    public TransferServiceImpl() {
    }
}

相关文章

此处评论已关闭