@Bean 小知识

先说结论

@Bean 可以用在任意方法上。 -- 也可以用在注解上面。

@Bean 仅在Spring创建bean时起作用。

这应该算一个小技巧,在一个平常类(非@Configuration class)中@Bean method,需要的时候直接导入该类即可。

补充一句,@Import 在 4.2 版本之前只能导入配置类,4.2及以后可以导入任意类。

 

再来说说起因

在看Spring Boot源码的时候,发现很多平常类(非@Configuration class)中都有 @Bean method,甚是疑惑。

开始以为 Spring 会直接探测 @Bean method,然后创建相应的bean。于是手动测试了一番,代码如下(Spring Boot项目):

public class _TestBean {

    @Bean(name = "joke")
    public User user() {
        User user = new User();
        user.setName("joke");
        return user;
    }
}
@Configuration
public class _TestBeanConfig {
    @Autowired
    @Qualifier("joke")
    private User    joke;
    @Autowired
    private User    user;

    @PostConstruct
    public void print() {
        System.out.println(joke);
        System.out.println("---");
        System.out.println(user);
    }

}

结果,启动失败,报错内容是user依赖不满足!

所以之前的推测明显不成立, Spring不会扫描平常类中的@Bean method

 

再次尝试

模仿Spring Boot源码中的使用方式:@Import

@Configuration
@Import(value = _TestBean.class)
public class _TestBeanConfig {
    @Autowired
    @Qualifier("joke")
    private User    joke;
    @Autowired
    private User    user;

    @PostConstruct
    public void print() {
        System.out.println(joke);
        System.out.println("---");
        System.out.println(user);
    }

}

再次启动,成功,并顺利打印出所需信息。

就是说,使用@Import时,Spring会扫描被导入的类中的@Bean method,并执行(创建相应bean)

查了下@Import,原文是这么说的:

Indicates one or more @Configuration classes to import. 

又查了下@Configuration,说法如下:

Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.

同时,@Configuration又被注解了@Component

于是推测,Spring 在创建bean时,就会扫描其中的 @Bean method

第三次测试如下:

@Component
public class _TestBean {

    @Bean(name = "joke")
    public User user() {
        User user = new User();
        user.setName("joke");
        return user;
    }
}
@Configuration
// @Import(value = _TestBean.class)
public class _TestBeanConfig {
    @Autowired
    @Qualifier("joke")
    private User    joke;
    @Autowired
    private User    user;

    @PostConstruct
    public void print() {
        System.out.println(joke);
        System.out.println("---");
        System.out.println(user);
    }

}

果然,顺利启动,并打印出所需信息。

 

于是得出最开始的结论

  @Bean 可以用在任意方法上。 -- 也可以用在注解上面。

  @Bean 仅在Spring创建bean时起作用。

 

posted on 2016-09-19 10:08  LarryZeal  阅读(581)  评论(0编辑  收藏  举报

导航