Spring是一个强有力的java程序框架其被广泛应用于java的程序中它用POJO提供了企业级服务Spring利用依赖注入可以获得简单而有效的测试能力Spring beans依赖关系以及服务所需要的bean都将在配置文件中予以描述配置文件一般采用XML格式然而XML配置文件冗长而不易使用在你进行一个使用了大量bean的大项目中它将变得难以阅读和控制
在这篇文章中我将给你展示种的有关Spring XML配置文件的最佳技巧它们中的一些具有更多的实际意义而不仅是最好的技巧请注意另外一些因素例如域模型的设计会影响到XML配置但是这篇文章更关注于XML配置的可读性和可操控性
. 避免使用自动装配
Spring可以通过bean类的自省来实现自动装配依赖这样的话你就不必明确地描述bean的属性或者构造函数的参数根据属性名称活匹配类型bean属性可以自动进行装配而构造函数可以根据匹配类型自动装配你甚至可以设置自动装配进行自动侦测这样Spring替你就会选择一个合适的机制请看下面的例子
Spring可以通过bean类的自省来实现自动装配依赖这样的话你就不必明确地描述bean的属性或者构造函数的参数根据属性名称活匹配类型bean属性可以自动进行装配而构造函数可以根据匹配类型自动装配你甚至可以设置自动装配进行自动侦测这样Spring替你就会选择一个合适的机制请看下面的例子
<bean id=orderService
class=comlizjasonspringOrderService
autowire=byName/>
OrderService类的属性名被用来和容器中的一个bean实例进行匹配自动装配会默默的保存一些类型信息并降低混乱然而由于它会牺牲掉这种配置的直观性和可维护性你在实际的项目中将不会用到它许多指南和陈述材料都把它吹捧为Spring的一个非常cool的特性而没有提到它的这个缺点依我之见就像Spring的对象池一样它更多了一些商业味道它看起来好像可以使XML配置文件更精简一些但实际上却增加其复杂性尤其是在你的较大规模的工程中已经定义了很多bean的时候更是如此Spring允许你混合使用自动和手动装配但是这种矛盾会使XML配置更加的令人费解
. 使用命名规范
和Java编码的理念一样在项目中始终用清晰的描述性的一致的命名规范对开发人员理解XML配置非常有用拿bean ID举例来说你可以遵循Java类中属性的命名规范比如说OrderServiceDAO的bean ID应该是orderServiceDAO对于大项目来说在bean ID前加包名来作为前缀
. 使用简化格式
简化格式有利于减少冗余因为它把属性值和引用作为属性而不是子元素看下面的例子
<bean id=orderService
class=comlizjasonspringOrderService>
<property name=companyName>
<value>lizjason</value>
</property>
<constructorarg>
<ref bean=orderDAO>
</constructorarg>
</bean>
以上程序可以重新以简化格式书写为
<bean id=orderService
class=comlizjasonspringOrderService>
<property name=companyName
value=lizjason/>
<constructorarg ref=orderDAO/>
</bean>
简化格式在版本时已经可用了但请注意不存在<ref local=>这种简化格式不仅可以较少你的代码输入量而且可以使XML配置更加的清晰当你的配置文件中存在大量的bean定义时它可以显着地提高可读性
. 尽量使用type而不是index去解决构造函数参数的匹配问题
当构造函数中有多个同类型的参数时Spring只允许你使用从开始的index或者value标签来解决这个问题请看下面的例子
<bean id=billingService
class=comlizjasonspringBillingService>
<constructorarg index= value=lizjason/>
<constructorarg index= value=/>
</bean>
最好用type属性取代上面的做法
<bean id=billingService
class=comlizjasonspringBillingService>
<constructorarg type=javalangString
value=lizjason/>
<constructorarg type=int value=/>
</bean>
用index可以稍微减少冗余但是它更容易出错且不如type属性可读性高你应该仅在构造函数中有参数沖突时使用index
. 如可能尽量复用bean定义
Spring提供了一种类似于继承的机制来降低配置信息的重复并使XML配置更加的简单一个子bean可以从它的父bean继承配置信息本质上这个父bean就像它的子bean的一个模板这是一个在大型项目中必须使用的特性所有你要做的就是把父bean的abstract属性置为true并在子bean中加以引用例如
<bean id=abstractService abstract=true
class=comlizjasonspringAbstractService>
<property name=companyName
value=lizjason/>
</bean>
<bean id=shippingService
parent=abstractService
class=comlizjasonspringShippingService>
<property name=shippedBy value=lizjason/>
</bean>
shippingService bean继承了abstractService bean的属性companyName的值lizjason注意如果你为bean声名一个class或工厂方法这个bean将会默认为abstract
. 尽量使用ApplicationContext装配bean而不是用import
像Ant脚本中imports一样Spring的import 元素对于模块化bean的装配非常有用例如
<beans>
<import resource=billingServicesxml/>
<import resource=shippingServicesxml/>
<bean id=orderService
class=comlizjasonspringOrderService/>
<beans>
然而比起在XML中用imports预装配这些bean利用ApplicationContext来配置它们将更加灵活也可以使XML配置更加的易于管理你可以像下面这样传递一个bean定义数组到ApplicationContext的构造函数中
String[] serviceResources =
{orderServicesxml
billingServicesxml
shippingServicesxml};
ApplicationContext orderServiceContext = new
ClassPathXmlApplicationContext(serviceResources);
. 用id来标识bean
你可以用id或名字作为bean的标识用id可读性较差但是它可以影响XML分析器使bean的reference有效如果id由于XML IDREF约束而无法使用你可以用name作为bean的标识XML IDREF约束是指id必须以字母开始(或者是在XML声名了的一个标点符号)后面可以是字母数字连字符下划线冒号或full stops(不知道怎么翻译好)在实际应用中很少会遇到XML IDREF约束问题
. 在开发阶段使用依赖检查
你可以为bean的dependencycheck属性设置一个值来取代默认的none比如说simpleobjects或者all这样的话容器将替你做依赖有效性的检查当一个bean的所有属性(或者某些属性目录)都被明确设置或利用自动装配时将会非常有用
<bean id=orderService
class=comlizjasonspringOrderService
dependencycheck=objects>
<property name=companyName
value=lizjason/>
<constructorarg ref=orderDAO/>
</bean>
在这个例子中容器将确保这些属性不是privitives或者保证collections是为orderService bean设置的为所有的bean设置默认的依赖检查是可能的但这个特性由于有些bean的属性不需要设置而很少使用
. 为每个配置文件加一个描述注释
在XML配置文件中最好使用有描述性的id和name而不是成堆的注释另外加一个文件描述头将会非常有用这个描述可以概括文件中定义的bean另一个选择你可以在description元素中加入描述信息例如
<beans>
<description>
This file defines billing service
related beans and it depends on
baseServicesxmlwhich provides
service bean templates
</description>
</beans>
用description元素的一个好处就是工具可以很容易的把描述信息从这个元素中提取出来
. 和team members沟通变更
当你修改java源码后要确保更改了配置文件中的相应部分并把这个情况告知你的team membersXML配置文件也是代码它们是程序的重要组成部分但它们很难阅读和维护大多数时间里你需要同时看XML配置文件和java代码才能知道是怎么回事
. setter注入和构造函数注入优先使用前者
Spring提供了三种注入方式构造函数注入setter注入和方法注入一般我们使用前两种
<bean id=orderService
class=comlizjasonspringOrderService>
<constructorarg ref=orderDAO/>
</bean>
<bean id=billingService
class=comlizjasonspringBillingService>
<property name=billingDAO
ref=billingDAO>
</bean>
在这个例子中orderService bean用了构造函数注入而BillingService bean用了setter注入构造函数注入可以确保bean正确地构建但是setter注入更加的灵活和易于控制特别是当class有多个属性并且它们中的一些是可选的情况是更是如此
. 不要滥用注入
就像前面提到的Spring的ApplicationContext可以替你创建java对象但不是所有的java对象都应该通过注入创建例如域对象就不应该通过ApplicationContext创建Spring是一个优秀的框架但是考虑到可读性和可操控性基于XML配置的配置会在定义很多bean的时候出现麻烦过渡使用依赖注入将会使XML配置更加的复杂和冗长切记当使用高效的IDE时例如Eclipse and IntelliJjava代码更加的易于阅读维护和管理比使XML文件
结论
XML是Spring流行的配置格式存在大量bean定义时基于XML的配置会变得冗长而不易使用Spring提供了丰富的配置选项适当地使用这些选项可以使XML配置更加的清晰但其它的一些选项例如自动装配可能会降低可读性和可维护性参考本文中提到的这些技巧可能会帮助你创建干净而易读的XML配置文件