用小说的形式讲解Spring(3) —— xml、注解和Java Config到底选哪个
来源:互联网 发布:四环医学网络学员登录 编辑:程序博客网 时间:2024/06/05 16:15
本文发布于专栏Effective Java,如果您觉得看完之后对你有所帮助,欢迎订阅本专栏,也欢迎您将本专栏分享给您身边的工程师同学。
本集概要:
- 为什么说xml配置是类型不安全的配置方式?
- 如何使用注解进行配置?
- 注解配置是万能的吗?
- 如何使用Java Config进行配置?
- xml、注解、Java Config,到底该如何选择?
大雄一脸懵逼,心想,“我不就改了一处地方,怎么就把服务器给整挂了呢”,他仔细地看了一下自己改的代码:
<bean id="serverLogger" class="com.springnovel.perfectlogger.CosoleLogger"/>
“啊!!原来是CosoleLogger拼错了…”
类型不安全的xml配置
到了公司,大雄跟哆啦讲了自己干的这件蠢事。
“小伙子,早上没睡醒吧,哈哈哈”
“额,你还笑得出来”
“其实吧,我有办法让你在没睡醒的时候也不会犯这种错误”
“啥办法,该不会是让我喝咖啡吧…”
“喝咖啡也没我这个办法管用,你小子之前学Spring的时候,不会只知道用xml这种类型不安全的方式来配置吧?”
“噢,好像还有其他配置方式…注解?还有Java Config…啊!我明白你的意思了,使用注解和Java Config,这样在我拼写错的时候,由于找不到这类,编译都不会通过,我也就知道我拼写错了!”
“就是罗,而且这只是其他配置方式优于xml配置的一点,你用过之后就会发现他们有更多的优点了”
“好,我这就试试用注解方式改造一下我们的代码!”
通过注解进行自动化装配
大雄决定先把原来PaymentAction中,使用xml配置的OrderDao,改为通过注解进行配置。
首先,大雄给OrderDao加上@Component注解,表明这个类是一个组件类,告诉Spring要为这个class创建bean,并注入给IOrderDao(本文使用的代码,可以到 SpringNovel 下载,欢迎加星):
@Componentpublic class OrderDao implements IOrderDao{ ......}
接着需要告诉Spring哪些包是需要进行扫描并自动装配,因此,大雄新建了一个配置类,然后使用@ComponentScan指明哪些包需要扫描:
@Configuration@ComponentScan(basePackageClasses={IOrderDao.class,PaymentActionMixed.class})public class PaymentConfig {}
这里的basePackageClasses是类型安全的,它的值是一个class数组,表明Spring将会扫描这些class所在的包。
最后需要使用@Autowired,把扫描到的OrderDao通过构造器注入的方式,注入到PaymentAction中:
@Componentpublic 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啰里啰嗦的配置,简直是太方便了!”大雄像发现了宝藏一样,赞叹着注解这项伟大的发明。
注解配置不是万能的
“注解好方便啊,而且注解的同时还能起到注释的作用,看到@Component注解就知道这个对象是组件,看到@Autowire就知道这里会进行注入,哆啦,我们项目以后都用注解进行配置吧!”
“哈哈,你小子对注解的理解还挺深入的嘛。你说都用注解进行配置?那你试试把早上害惨你的ConsoleLogger改成注解注入试试?”
“这还不简单哦,不就加几个注解的事儿吗……”大雄说完,准备找地方加上@Component注解。
“啊,不对,这个类又不是我们写的,这是我们引用的第三方的jar包……我们改不了它的源码啊……”
“哈哈哈,你才发现啊?你刚刚不是还说以后都用注解吗?”
“啊,那看来这里还是得有类型不安全的、啰里啰嗦的xml进行配置了……”
“是咩?小伙子记性不行啊!”
“啊对,还有一种配置方式……Java Config!”
使用Java代码进行注入
“啊啊,我有种预感,这种配置方式是自由度最高的,因为他叫Java Config,顾名思义,就是通过Java代码的方式进行注入,终于可以自己写代码进行注入了,xml和注解都感觉好没劲!”大雄兴奋的说道,摩拳擦掌。
“哈哈,看来你骨子里面还是特别热爱编码的嘛!”
“那是!”
唠完嗑,大雄开始着手使用Java Config的配置方式来注入第三方jar包里的ConsoleLogger。
使用Java Config,只需要创建一个配置类,在配置类中编写方法,返回要注入的对象,并给方法加上@Bean注解,告诉Spring为返回的对象创建实例:
@Configurationpublic 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 100ConsoleLogger: pay end
“Java Config也是非常方便,虽然要写的代码比注解多了不少,但是一方面,相比于注解配置,Java Config**对代码没有侵入,可以注入代码不是自己维护的类;另一方面,Java Config是使用Java代码进行注入的,相比于xml来说,又更为自由**”
“嗯嗯,总结的不错。”哆啦拍拍大雄的肩膀,继续说道,“不知不觉你已经在项目开发的过程中,把Spring的两大特性其中的一个,也就是控制反转的使用方式给用了个遍了,对这三种方式的优劣,相信你也有一个大致的认识,晚上回去总结一下,当然,你也可以上网找找资料,看看别人是怎么在这三种配置方式中进行取舍的……”哆啦滔滔不绝,开启了导师模式…….
“哎呀呀,明白了,我晚上跟静香……哦不,我晚上吃完饭回去就写写总结……”
大雄的笔记
今天大雄又掌握了Spring依赖注入的另外两种配置方式——注解和Java Config,是时候把这三种方式做个总结了:
这么总结下来一看,这三种配置方式,真可谓是各有千秋,不过在选择上还是有一定的规律的:
- xml配置相对于其他两种方式来说,几乎没什么优势,唯一的优势就是修改后不需要重新编译,因此对于一些经常切换实现类的对象,可以采用xml的方式进行配置。还有就是由于xml是Spring一开始就提供的配置方式,因此很多旧代码还是采用xml,所以在维护旧代码时会免不了用到xml。
- 注解用起来非常地简洁,代码量十分少,因此是项目的第一选择。只有当需要注入代码不是自己维护的第三方jar包中的类时,或者需要更为灵活地注入,比如说需要调用某个接口,查询数据,然后把这个数据赋值给要注入的对象,那么这时候就需要用到Java Config。
未完待续
整合了Spring IOC功能的商城项目在国庆前一天顺利上线,胖虎十分高兴,请大家伙去他家吃大餐。
好多同事都听说了大雄的“丰功伟绩”,纷纷过来敬酒,不会挡酒的大雄很快喝的醉醺醺的,迷迷糊糊中,他似乎看到了胖虎站了起来,说道,“商城项目终于上线了,国庆回来后,我们有一个更重要的项目,经过这次商城项目的经验,公司决定从一开始就采用SpringMVC进行开发,哆啦担任项目经理,大雄是开发组长……”
“啊…..”,大雄朦朦胧胧的双眼似乎看到了静香向他投来崇拜的目光,大雄痴痴地笑着,突然,他眼里出现了穿着比基尼的静香…
“啊,静香,你这件比基尼…真…真好看…”
参考内容
- 《Spring in Action》
- Spring Dependency Injection Styles - Why I love Java based configuration - codecentric AG Blog
- Spring Framework – XML vs. Annotations - DZone Java
- xml configuration versus Annotation based configuration
- Spring annotation-based DI vs xml configuration?
- Java Dependency injection: XML or annotations
- 用小说的形式讲解Spring(3) —— xml、注解和Java Config到底选哪个
- 用小说的形式讲解Spring(1) —— 为什么需要依赖注入
- 用小说的形式讲解Spring(2) —— 注入方式哪家强
- 用小说的形式讲解Spring(4) —— 使用Spring Boot创建NoXml的Web应用
- Spring定时器的使用(注解+xml形式)
- .net和java到底该选哪个————.net和java对比
- Spring的注解形式
- Spring的注解形式
- 依赖注入(DI)和控制反转(IOC)的详细讲解 spring容器(spring注解实现,而不是xml配置文件)
- 3DMAX和MAYA到底哪个强—转载
- 【SSH】注解和非注解的形式配置Spring
- Aspect 切点表达式(xml形式,非注解形式的)
- Spring中bean的初始化和销毁之前的方法XML和注解的两种形式
- Spring的注解形式:@Repository
- spring系列(二)——AOP的两种实现方式(xml和注解)
- Spring学习(六)spring整合注解形式的hibernate
- DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?
- DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?
- Kotlin实战(二): 实现RecyclerView多种Item布局
- 【第八章】操作符重载的概念
- EPCON_SINET_V6.11-LND\
- 有技巧,写作如有神助
- Kotlin学习(十二): 函数、高级函数和Lambda表达式
- 用小说的形式讲解Spring(3) —— xml、注解和Java Config到底选哪个
- 在Linux dtsi文件中删除一个Node
- Kotlin学习(十三): 集合(Collections)和范围(Ranges)
- 浅谈Hybrid技术——Big-man
- Java 三大框架介绍
- 采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法,终极解决方案.
- Kotlin学习(十四): 类型别名(Type aliases)和注解(Annotations)
- Microsoft SQL Server学习(七)--函数视图
- 聊天室(c/s架构)