Spring注解之@Configuration和@Bean使用详解

栏目: 编程语言 · XML · 发布时间: 5年前

内容简介:Spring3.0之前要使用Spring必须要有一个xml配置文件,而Spring3.0之后注解慢慢登上舞台,通过注解Spring 3.0新增了另外两个实现类:AnnotationConfigApplicationContext 和 AnnotationConfigWebApplicationContext。它们是为注解而生,直接依赖于注解作为容器配置信息来源的IoC容器初始化类。AnnotationConfigWebApplicationContext是AnnotationConfigApplicatio

Spring3.0之前要使用Spring必须要有一个xml配置文件,而Spring3.0之后注解慢慢登上舞台,通过注解 @Configuration@Bean 可以完全搞定。此时,注解和xml配置形成了相互协作与竞争的关系。随着Springboot的推广,注解的使用在Spring中大放光彩,xml的辉煌一去不返。通过注解,简化了配置,提升了编码效率。

Spring 3.0新增了另外两个实现类:AnnotationConfigApplicationContext 和 AnnotationConfigWebApplicationContext。它们是为注解而生,直接依赖于注解作为容器配置信息来源的IoC容器初始化类。AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的web版本,其用法与后者相比几乎没有什么差别。

今天这篇文章带大家学习 @Configuration@Bean 的使用,并通过具体的实例体验一下注解的方便快捷。如果你的项目中还未曾使用此类注解,说明你的技术栈已经在被淘汰的边缘。

基于 Java 类的配置选项

Spring 3.0引入了注解,配置文件的载体就从xml文件转换为了Java类,Java类就是一个普通的类,除了命名建议以“**Config”结尾方便识别外,Spring对其有一定的约定条件。

  • 配置类不能是 final 类(没法动态代理)。
  • 配置类必须是非本地的(即不能将配置类定义在其他类的方法内部,不能是private)。
  • 配置类必须有一个无参构造函数。

基本使用方法

符合上述条件的类,就可以使用 @Configuration 来进行注解,表示这个类可以使用Spring IoC容器作为bean定义的来源。 @Bean 注解在该类的方法上,AnnotationConfigApplicationContext将配置类中标注了 @Bean 的方法的返回值识别为Spring Bean,并注册到容器中,归入IoC容器管理。

@Configuration 的作用等价于XML配置中的<beans/>标签, @Bean 的作用等价于XML配置中的<bean/>标签。下面代码完成了一个简单的示例。

@Configuration
public class DataSourceConfig {
    @Bean
    public MysqlDataSource mysqlDataSource() {
        return new MysqlDataSource();
    }

    @Bean(name = "oracleDataSource")
    public OracleDataSource oracleDataSource() {
        return new OracleDataSource();
    }
}

Spring在解析该类时,会识别出标注 @Bean 的所有方法,执行并将方法的返回值(MysqlDataSource和OracleDataSource对象)注册到IoC容器中。默认情况下,方法名即为Bean的名字。与以上配置等价的XML配置如下:

<bean id="mysqlDataSource" class="**.MysqlDataSource"/> 
<bean id="oracleDataSource" class="**.OracleDataSource"/>

@Configuration 的属性

@Configuration 的定义代码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    String value() default "";
}

@Configuration 注解本身定义时被 @Component 标注了,因此本质上来说 @Configuration 也是一个 @Component ,只不过我们在具体使用的过程中基本用不到它的实例化对象。

@Bean 属性

@Bean 注解的具体代码定义:

@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)";
}

可以看出 @Bean 具有以下属性:

  • name :指定一个或者多个Bean的名字。等价于XML配置中<bean>的name属性,示例中的 @Bean (name = “oracleDataSource”)。
  • initMethod:容器在初始化完Bean之后,会调用该属性指定的方法。等价于XML配置中<bean>的init-method属性。
  • destroyMethod:该属性与initMethod功能相似,在容器销毁Bean之前,会调用该属性指定的方法。等价于XML配置中<bean>的destroy-method属性。
  • autowire:指定Bean属性的自动装配策略,取值是Autowire类型的三个静态属性。Autowire.BY_NAME,Autowire.BY_TYPE,Autowire.NO。与XML配置中的autowire属性的取值相比,少了constructor,因为 constructor在这里已经没有意义了。

@Bean 默认是单例模式,并且没有提供指定作用域的属性,可以通过 @Scope 来实现该功能。

@Bean
@Scope("prototype")
public MysqlDataSource mysqlDataSource() {
    return new MysqlDataSource();
}

Spring扫描加载

当配置完Spring扫描指定包及其子包中的类时,会识别所有标记了 @Component@Controller@Service@Repository 注解的类,由于 @Configuration 注解本身也用 @Component 标注了,Spring将能够识别出 @Configuration 标注类。

实例

现在对上面的示例进行单元测试,其中MysqlDataSource和OracleDataSource类中分别提供了打印日志的方法:

public void print(){
    System.out.println("I am MysqlDataSource!");
}
和
public void print(){
    System.out.println("I am OracleDataSource!");
}

指定单元测试的代码如下:

public class ConfigBeanTest {

    @Test
    public static void testGetBean() {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(DataSourceConfig.class);
        MysqlDataSource mysqlDataSource = ctx.getBean(MysqlDataSource.class);
        mysqlDataSource.print();
    }
}

当执行单元测试,成功打印出:

I am MysqlDataSource!

实战技巧

如果我们在DataSourceConfig中再添加一个方法,这个方法用到了前面实例化的两个bean对象,那么该如何处理?常规的想法是在DataSourceConfig中添加如下代码,然后再直接使用属性:

@Autowired
private MysqlDataSource mysqlDataSource;

其实不必如此,直接调用方法mysqlDataSource()方法即可。比如,需要新增下面类的实例化:

public class CommonDataSource {

    private MysqlDataSource mysqlDataSource;

    private OracleDataSource oracleDataSource;
    // 省略getter/setter方法
}

那么,我们只用在DataSourceConfig中添加如下代码即可:

@Bean
public CommonDataSource commonDataSource() {
    CommonDataSource commonDataSource = new CommonDataSource();
    commonDataSource.setMysqlDataSource(mysqlDataSource());
    commonDataSource.setOracleDataSource(oracleDataSource());
    return commonDataSource;
}

注意:set方法内直接set的是mysqlDataSource()。

小结

这节课我们讲解了Spring注解中 @Configuration@Bean 使用方法,在Springboot中集成其他三方框架时,这种写法使用的越来越普遍。如果一时无法转换思维,可对照xml文件的配置进行逐一切换过来,比如xml要定义一个bean,那么用注解就是 @Bean 注解一个方法。如果方法里面的参数还有其他的依赖,那就采用上面介绍的实战技巧依次追踪set对应的参数,并将其先通过 @Bean 实例化。

本节代码中使用到了 @Configuration@Bean 的源代码,如果你对注解的使用不太熟悉可参考《一篇文章,全面掌握Java自定义注解(Annontation)》一文。

Spring注解之@Configuration和@Bean使用详解


以上所述就是小编给大家介绍的《Spring注解之@Configuration和@Bean使用详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First jQuery

Head First jQuery

Ryan Benedetti , Ronan Cranley / O'Reilly Media / 2011-9 / USD 39.99

Want to add more interactivity and polish to your websites? Discover how jQuery can help you build complex scripting functionality in just a few lines of code. With Head First jQuery, you'll quickly g......一起来看看 《Head First jQuery》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具