文章506
标签266
分类65

Spring中xml、注解和JavaConfig到底选哪个

xml、注解和JavaConfig作为Spring中常用的三种配置方式有何区别, 三种方法分别适用于什么场合, 本篇文章为您一一解答.

本文概要:

  • 为什么说xml配置是类型不安全的配置方式?
  • 如何使用注解进行配置?
  • 注解配置是万能的吗?
  • 如何使用Java Config进行配置?
  • xml、注解、Java Config,到底该如何选择?

Spring中的配置xml、注解和JavaConfig

一. 类型不安全的xml配置

通过XML进行的配置容易产生笔误, 如:

<bean id="serverLogger" class="com.springnovel.perfectlogger.CosoleLogger"/>

如上, 笔误CosoleLogger拼写成了CosoleLogger, 对于IDEA这种无敌的编辑器而言, 这种错误可以避免;



二. 通过注解进行自动化装配

1): 通过注解进行装配的例子

例: 将原来PaymentAction中,使用xml配置的OrderDao,改为通过注解进行配置;

首先,给OrderDao加上@Component注解,表明这个类是一个组件类,告诉Spring要为这个class创建bean,并注入给IOrderDao

@Component
public class OrderDao implements IOrderDao{
    ......
}

接着需要告诉Spring哪些包是需要进行扫描并自动装配. 因此,新建了一个配置类,然后使用@ComponentScan指明哪些包需要扫描:

@Configuration
@ComponentScan(basePackageClasses={IOrderDao.class,PaymentActionMixed.class})
public class PaymentConfig {

}

这里的basePackageClasses是类型安全的,它的值是一个class数组,表明Spring将会扫描这些class所在的包


最后需要使用@Autowired,把扫描到的OrderDao通过构造器注入的方式,注入到PaymentAction中:

@Component
public class PaymentActionMixed {

    ......
    private IOrderDao orderDao;

    ......

    @Autowired
    public PaymentActionMixed(IOrderDao orderDao) {
        super();
        this.orderDao = orderDao;
    }

    ......

    public void addOrder(String orderType) {
        orderDao.addOrder(orderType);
    }

}

测试: 这里使用了SpringJUnit4ClassRunner以便于在测试开始的时候自动创建Spring的上下文,使用@ContextConfiguration告诉Spring要加载什么配置:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=PaymentConfig.class)
public class PaymentMixedTest {

    @Autowired
    private PaymentActionMixed paymentActionMixed;

    @Test
    public void testPaymentMixedAddOrder() {
        paymentActionMixed.addOrder("create_sub");
    }
}

Output:

real add order, order type is create_sub

仅仅用了几个注解,就成功地将OrderDao注入到PaymentAction里面了!比起xml啰里啰嗦的配置,简直是太方便了!


2): 注解并非万能

对于第三方的jar包, 由于我们无法修改源码, 所以没办法在源码上添加注解!



三.使用Java代码进行注入

这种配置方式是自由度最高的,顾名思义,就是通过Java代码的方式进行注入!

例如: 使用JavaConfig的配置方式来注入第三方jar包里的ConsoleLogger

使用Java Config,只需要创建一个配置类,在配置类中编写方法,返回要注入的对象,并给方法加上@Bean注解,告诉Spring为返回的对象创建实例:

@Configuration
public class PaymentJavaConfig {

    @Bean
    public ILogger getIlogger() {
        return new ConsoleLogger();
    }

    @Bean
    public PaymentActionMixed getPaymentActionMixed(ILogger logger)     {
        return new PaymentActionMixed(logger);
    }

接着就可以进行测试了:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = PaymentJavaConfig.class)
public class PaymentJavaConfigTest {

    @Autowired
    private PaymentActionMixed paymentActionMixed;

    @Test
    public void testPaymentMixedAddOrder() {
        paymentActionMixed.pay(new BigDecimal(100));
    }
}

Output:

ConsoleLogger: pay begin, payValue is 100
ConsoleLogger: pay end

Java Config也是非常方便,虽然要写的代码比注解多了不少,但是:

一方面,相比于注解配置,Java Config对代码没有侵入,可以注入代码不是自己维护的类;

另一方面,Java Config是使用Java代码进行注入的,相比于xml来说,又更为自由



四. 总结

三种配置方式比较:


特点\配置方式 XML 注解 Java Config
类型是否安全 N Y Y
查找实现类是否方便 N,需要查找所有xml Y,只需看哪个实现类上有加注解 N,需要查找所有Java Config
可读性 差,有很多xml标签,不易阅读 很好,注解的同时起到注释的作用 较好,对于Java程序员来说,阅读Java代码比阅读xml方便
配置简洁性 很啰嗦 十分简洁 有点啰嗦
修改配置是否需要重新编译 N,直接替换xml文件即可 Y,需重新编译出class文件,然后进行替换 Y,同注解配置
是否会侵入代码 N Y N
自由度 低,可以使用SPEL语法,但是SPEL语法能实现的功能有限 低,只能基于注解的属性进行配置 高,可以自由使用Java语法,调用各种函数来注入对象
是否可以注入不是自己维护的类 Y N Y

这么总结下来一看,这三种配置方式,真可谓是各有千秋,不过在选择上还是有一定的规律的:

  • xml配置: 相对于其他两种方式来说,几乎没什么优势,唯一的优势就是修改后不需要重新编译,因此对于一些经常切换实现类的对象,可以采用xml的方式进行配置;还有就是由于xml是Spring一开始就提供的配置方式,因此很多旧代码还是采用xml,所以在维护旧代码时会免不了用到xml;

  • 注解: 用起来非常地简洁,代码量十分少,因此是项目的第一选择;

  • Java Config: 只有当需要注入代码不是自己维护的第三方jar包中的类时,或者需要更为灵活地注入,比如说需要调用某个接口,查询数据,然后把这个数据赋值给要注入的对象,那么这时候就需要用到



附录

文章引用:


本文作者:Jasonkay
本文链接:https://jasonkayzk.github.io/2019/09/23/Spring中xml、注解和JavaConfig到底选哪个/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可