Spring是一个强大的JAVA应用框架,广泛地应用于JAVA的应用程序。为Plain Old Java Objects(POJOs)提供企业级服务。Spring利用依赖注入机制来简化工作,同时提高易测性。Spring beans及依赖,以及beans类所需的服务都在配置文件中进行了详细的说明,这个配置文件是典型的XML格式。但是它既冗长又不实用。对于需要定义大量Spring beans的大工程来说,我们难以阅读和管理它。

版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:Jason;Li;evenbetter(作者的blog:http://blog.matrix.org.cn/page/evenbetter)
原文:http://www.onjava.com/pub/a/onjava/2006/01/25/spring-xml-configuration-best-practices.html
译文:http://www.matrix.org.cn/resource/article/44/44236_Spring+XML+Configurations.html
关键字:Spring;XML;Configurations

在这篇文章里,对于Spring XML的配置,我将向你展示12种比较好的实践。其中的一些实践不仅是好的实践,更是必要的实践。除此以外,还有其他因素,例如领域模型的设计,都能影响XML的配置,但是这篇文章重点研究XML配置的易读性和易管理性。

1.不要使用autowiring
Spring可以通过类的自省来自动绑定其依赖部分,使得你不必明确指明bean的属性和构造器。Bean的属性可以通过属性名称或类型匹配来实现自动绑定。构造器通过类型匹配来实现自动绑定。你甚至可以指定自动检测自动绑定模式,它可以引导Spring选择一种适当的运行机制。先来看看下面的一个例子:

    <bean id="orderService"class="com.lizjason.spring.OrderService"autowire="byName"/>

OrderService类的属性名在容器中用于匹配bean实例。自动绑定可以潜在地节省一些打字和减少一些混乱。但是在现实世界的工程里你不应该使用这种方式,这是因为它牺牲了配置的清晰性和可维护性。许多指南和介绍中大量吹捧自动绑定是Spring的一种极好的特征而没有提到这一特性所带来的牺牲。依我的观点,这就像Spring中的object-pooling,它更像是一种为了占据更多市场的商业特征。它对于XML配置文件的小巧化是一个好办法,但实际上也增加了复杂程度,尤其当你运行有大量类声明的工程时。虽然Spring允许你混合自动绑定和手动绑定,但是这个矛盾会使XML配置更加晦涩难懂。

2.使用通俗的命名
这个方式对于Java编码也一样适用。在工程中使用清晰的、描述性的、协调的通俗名称对于开发者理解XML配置是十分有益的。例如对于bean ID,你可以根据通俗的Java类名来命名它。对于例子中OrderServiceDAO的bean ID命名为orderServiceDAO。对于大的工程,你可以在bean ID前面加上包名作为前缀。

3. 使用简洁的形式
简洁形式避免了冗长,是因为它从子元素中将属性值和参考写到属性中。例如下面的例子:

    <bean id="orderService"class="com.lizjason.spring.OrderService"><property name="companyName"><value>lizjason</value></property><constructor-arg><ref bean="orderDAO"></constructor-arg></bean>

可以使用简洁形式将上述代码重写为:

    <bean id="orderService"        class="com.lizjason.spring.OrderService">        <property name="companyName"            value="lizjason"/>        <constructor-arg ref="orderDAO"/>    </bean>

简洁形式功能在1.2版本中可以使用。对于<ref local="...">没有简洁形式。
简洁形式不但可以节约你的打字,而且可以使XML配置文件清晰。它最引人注目的是当在一个配置文件中有大量定义的类时可以提高易读性。

4. 对于构造器参数匹配,类型名比序号好。
当一个构造器含有一个以上的同种类型的参数,或者属性值的标签已经被占用时,Spring允许你使用从0计数的序号来解决这些会带来混淆的问题。例如:

    <bean id="billingService"class="com.lizjason.spring.BillingService"><constructor-arg index="0" value="lizjason"/><constructor-arg index="1" value="100"/></bean>

像下面这样,利用类型属性来编写会更好一些:

    <bean id="billingService"        class="com.lizjason.spring.BillingService">        <constructor-arg type="java.lang.String"            value="lizjason"/>        <constructor-arg type="int" value="100"/>    </bean>

使用索引可以稍稍减少一些冗长,但是和使用类型属性相比,它还是有容易发生错误的倾向和难于阅读的缺点。你应该只在构造器参数不明确的时候,才使用索引这一方法。

5. 尽可能重用已定义过的bean
Spring提供一种类似继承一样的机制来减少配置信息的复制并简化XML配置。定义一个子类可以从它父类那里继承配置信息,而父类实质上作为子类的一个模板。这就是大工程中所谓的重用。你所需要做的就是在父类bean中设置abstract=true,然后在子bean注明它自己的父类bean。例如:

    <bean id="abstractService" abstract="true"class="com.lizjason.spring.AbstractService"><property name="companyName"value="lizjason"/></bean>

<bean id="shippingService"parent="abstractService"class="com.lizjason.spring.ShippingService"><property name="shippedBy" value="lizjason"/></bean>

ShippingService类从abstractService类那里继承companyName属性的值——lizjason。如果你没有为一个bean指明类或factory方法,那么这个bean便是抽象的。

6. 尽量使用ApplicationContext来装配定义的bean
像在Ant脚本中的引用一样,Spring的引用对于装配模块化的bean来说是很有用的。例如:

    <beans>        <import resource="billingServices.xml"/>        <import resource="shippingServices.xml"/><bean id="orderService"class="com.lizjason.spring.OrderService"/><beans>

相对于使用import在XML配置中来预装配,通过ApplicationContext来配置这些beans,显得更加灵活。利用ApplicationContext也使得XML配置易于管理。你可以像下面的例子那样在ApplictionContext构造器里布置bean:

    String[] serviceResources ={"orderServices.xml","billingServices.xml","shippingServices.xml"};ApplicationContext orderServiceContext = newClassPathXmlApplicationContext(serviceResources);

7. 利用id作为bean的标识符
你可以指定一个id或名称来作为bean的标识符。虽然使用id不会提高易读性,但是它可以让XML parser对bean的引用有效方面进行更好的验证。如果由于XML IDREF的限制而不能使用某个id,你可以利用names来作为bean的标识符。XML IDREF的限制是id必须以字母开头(或者在XML规范中定义的标点符号),后面接着字母,数字,连字号,下划线,冒号等。实际上,遇到XML IDREF限制的问题是很少见的。

8. 在开发阶段使用依赖检验
你可以在bean中给依赖检验的属性设置值,而不采用原先默认的空值,属性设置例如simple,object或all,以便容器进行依赖检验。当bean的全部的属性(或某类属性)需要被明确设置或自动绑定时,依赖检验便显得很有用。

    <bean id="orderService"class="com.lizjason.spring.OrderService"dependency-check="objects"><property name="companyName"value="lizjason"/><constructor-arg ref="orderDAO"/></bean>

在这个例子里,容器确保为orderService bean设置的属性不是primitives 或者 collections。为所有的bean设置默认依赖检测也是可以的,但是我们很少这样做,是因为有些bean的属性根本就不必设置。

9. 为每个配置文件加上一个header comment
最好使用descriptive id和名称来代替在XML配置文件中的注释。此外,加上一个配置文件header也很有用处,它可以概述文件中所定义的bean。你可以选择将描述内容加入description标签中。例如:

    <beans><description>This file defines billing servicerelated beans and it depends onbaseServices.xml,which providesservice bean templates...</description>...</beans>

使用description标签的一个好处是可以容易地利用工具从标签中选取出description(的内容)。

10. 对于任何变化,要与队友积极交流
当你重构Java代码时,你需要随时更新配置文件并且通知队友。XML配置文件也是代码,它们是应用程序的至关重要的部分,但是它们难于阅读和维护。大部分时间你既要阅读XML配置文件又要阅读运行中的Java代码。

11. Setter injection优于constructor injection
Spring提供3种类型的依赖注入: constructor injection,setter injection, 和method injection。我们一般只用前两种类型。

    <bean id="orderService"class="com.lizjason.spring.OrderService"><constructor-arg ref="orderDAO"/></bean>

<bean id="billingService"class="com.lizjason.spring.BillingService">        <property name="billingDAO"            ref="billingDAO"></bean>

这个例子中,orderService类使用的是constructor injection,而BillingService类使用的是setter injection。constructor injection可以确保bean不会在一个非法状态下被创建,但是setter injection更加灵活并且更易管理,尤其当类存在很多属性并且其中一些是可选的情况下。

12. 不要滥用依赖注入
作为最后一点,Spring ApplicationContext可以替你创建Java对象,但是并不是所有的Java对象都通过依赖注入来创建的。例如,全局的对象不应该通过ApplicationContext来创建。Spring是一个很棒的框架,但是,就易读性和易管理性而言,当定义大量bean的时候,基于XML的配置问题就会突出。过度的依赖注入会使XML配置变得复杂而且臃肿。记住!使用强大的IDE时,例如Eclipse和IntelliJ,与XML文件相比,Java代码更加易读,易维护,易管理。

总结
对于Spring的配置,XML是很优秀的方式。但当定义大量bean时,基于XML配置会变得冗长,笨拙。Spring提供了丰富的配置选项。适当地利用其中的选项可以使XML配置清晰,但是,有些选项,例如autowiring(自动绑定),往往会降低易读性和易维护性。文章中所列举的实例,可以帮助你创建出清晰易读的XML配置文件。

关于作者:
Jason Zhicheng Li是Object Computing, Inc. in St. Louis, MO(公司)一名资深的软件工程师。

本文转自 zhenjing 博客园博客,原文链接:http://www.cnblogs.com/zhenjing/archive/2013/01/28/spring_config.html   ,如需转载请自行联系原作者

[转] Spring XML配置十二个最佳实践相关推荐

  1. Spring Boot(十二)集成spring-boot-starter-mail发送邮件

    项目GitHub地址 : https://github.com/FrameReserve/TrainingBoot Spring Boot(十二)集成spring-boot-starter-mail发 ...

  2. Spring xml 配置使用外部config 文件

    Spring xml 配置使用外部config 文件 当使用Spring framework后, 我们一般会把db connection的信息写在spring的bean config xml里面. 例 ...

  3. Spring boot(十二):Spring boot 如何测试、打包、部署

    博文引用:springboot(十二):springboot如何测试打包部署 开发阶段 单元测试 Spring boot对单元测试的支持已经很完善了. 1 在pom包中添加Spring-boot-st ...

  4. Spring cloud系列十二 监控Hystrix界面:Hystrix dashboard 和 Turbine

    1. 概述 为了更好的监控Hystrix的性能,Spring Cloud提供Hystrix dashboard和Turbin来达到这个目的. Hystrix dashboard可以实时监控Hystri ...

  5. Spring xml配置式的拦截器

    传统的xml配置式使用拦截器拦截请求. 一.Web.xml配置 在Web.xml 配置Spring核心控制器DispatcherServlet接收所有请求. <servlet><se ...

  6. spring.xml配置类属性--喜闻乐见

    相信大家在开发的过程中,都会写一些配置文件或者配置类来,毕竟好的编码习惯是不能硬编码的,所以配置文件和配置类就显得很重要了.但是我用久了之后发现,配置文件和配置类确实好用,但是假如有多个配置的话,那么 ...

  7. Spring Batch在大型企业中的最佳实践

    在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是" ...

  8. MBG配置详解及最佳实践

    2019独角兽企业重金招聘Python工程师标准>>> 为了在项目中引入MyBatis框架,最近一直在研究MyBatis的一套东西,MyBatis本身.MyBatis Spring. ...

  9. OPEN(SAP) UI5 学习入门系列之二: 最佳实践练习(上)

    这篇博文难产了很久,原来是打算一周更新一篇的,上周原计划写MVC,但是写了一半,发现带入了太多的细节,不太符合这个入门系列的主题. 当我们学习一个新的技能的时候,如果一开始就面对大量的细节,很容易陷入 ...

最新文章

  1. 判断dataset是否为空
  2. 刚过国家线计算机考研报哪个好,考研估分刚过了去年国家线,今年上岸还有希望吗?有!...
  3. 不用se11创建表结构,作smartforms
  4. tp5更新某字段加1_爱可生详解MySQL 8.0:索引特性1-函数索引
  5. Boost:bimap双图的突变的测试程序
  6. 微信跳一跳python全部代码_微信跳一跳python代码
  7. 选择最好用的PyCharm IDE
  8. 最优子结构(Optimal Substructure)
  9. 如何在使用ASPMVC4的分部视图中获取数据展示
  10. 领域驱动设计学习心得
  11. Java内部类的使用小结
  12. scrapy middlewares.py
  13. petshop4.0 详解之七(PetShop表示层设计)
  14. Qt学习 QVariant类(转)
  15. 让UITableView数据处理更轻便
  16. android 进入三方应用动画,Android 动画各种实现总结分享 AndroidAnimationExercise
  17. Fgui Glist 实现无限滑动 虚拟列表
  18. 播布客教学视频_C学习笔记_8.2_统计1到100中9的个数(函数)
  19. 学习python-day02-25---转自Python分布式爬虫打造搜索引擎Scrapy精讲
  20. 华为云迁移工具推荐最佳实践:Xen虚拟化迁移到华为云

热门文章

  1. Tomcat 8默认工具manager管理页面访问配置
  2. Selenium定位多个iframe嵌套中的元素
  3. poj 1247 Magnificent Meatballs 解题报告
  4. python之---Python深入06 Python的内存管理
  5. 奥比中光ROS启动节点运行异常退出:[camera/driver-2] process has finished cleanly
  6. 视觉slam学习笔记以及课后习题《第五讲特征点法视觉里程计》
  7. 数据结构笔记(四)-- 静态链表实现
  8. java的robot_Java中的Robot不执行命令
  9. c++工程模式+配置文件+动态调用类
  10. mysql if join_如何在MySQL中使用JOIN编写正确的If … Else语句?