Spring是一个强有力的java程序框架,其被广泛应用于java的程序中。
它用POJO提供了企业级服务。
Spring利用依赖注入可以获得简单而有效的测试能力。
Spring beans,依赖关系,以及服务所需要的bean都将在配置文件中予以描述,配置文件一般采用XML格式。
然而XML配置文件冗长而不易使用,在你进行一个使用了大量bean的大项目中它将变得难以阅读和控制。
在这篇文章中我将给你展示12种的有关Spring XML配置文件的最佳技巧。
它们中的一些具有更多的实际意义,而不仅是最好的技巧。
请注意另外一些因素,例如域模型的设计,会影响到XML配置,但是这篇文章更关注于XML配置的可读性和可操控性。
1.避免使用自动装配Spring 可以通过bean类的自省来实现自动装配依赖,这样的话你就不必明确地描述bean 的属性或者构造函数的参数。
根据属性名称活匹配类型,bean属性可以自动进行装配。
而构造函数可以根据匹配类型自动装配。
你甚至可以设置自动装配进行自动侦测,这样Spring 替你就会选择一个合适的机制。
请看下面的例子:Spring 可以通过bean类的自省来实现自动装配依赖,这样的话你就不必明确地描述bean 的属性或者构造函数的参数。
根据属性名称活匹配类型,bean属性可以自动进行装配。
而构造函数可以根据匹配类型自动装配。
你甚至可以设置自动装配进行自动侦测,这样Spring 替你就会选择一个合适的机制。
请看下面的例子:<bean id="orderService"class="com.lizjason.spring.OrderService"autowire="byName"/>OrderService 类的属性名被用来和容器中的一个bean实例进行匹配。
自动装配会默默的保存一些类型信息并降低混乱。
然而,由于它会牺牲掉这种配置的直观性和可维护性,你在实际的项目中将不会用到它。
许多指南和陈述材料都把它吹捧为Spring的一个非常cool的特性,而没有提到它的这个缺点。
依我之见,就像Spring的对象池一样,它更多了一些商业味道。
它看起来好像可以使XML配置文件更精简一些,但实际上却增加其复杂性,尤其是在你的较大规模的工程中已经定义了很多bean的时候更是如此。
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配置更加的清晰。
当你的配置文件中存在大量的bean 定义时,它可以显著地提高可读性。
4.尽量使用type而不是index去解决构造函数参数的匹配问题当构造函数中有多个同类型的参数时,Spring只允许你使用从0开始的index或者value标签来解决这个问题。
请看下面的例子:<bean id="billingService"class="com.lizjason.spring.BillingService"><constructor-arg index="0" value="lizjason"/><constructor-arg index="1" value="100"/></bean>最好用type属性取代上面的做法:<bean id="billingService"class="com.lizjason.spring.BillingService"><constructor-arg type="ng.String"value="lizjason"/><constructor-arg type="int" value="100"/></bean>用index可以稍微减少冗余,但是它更容易出错且不如type属性可读性高。
你应该仅在构造函数中有参数冲突时使用index。
5.如可能,尽量复用bean定义Spring 提供了一种类似于继承的机制来降低配置信息的重复并使XML配置更加的简单。
一个子bean可以从它的父bean继承配置信息,本质上这个父bean就像它的子bean的一个模板。
这是一个在大型项目中必须使用的特性。
所有你要做的就是把父bean的abstract属性置为true,并在子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 bean继承了abstractService bean的属性companyName的值lizjason。
注意,如果你为bean声名一个class或工厂方法,这个bean将会默认为abstract6.尽量使用ApplicationContext装配b ean,而不是用import像Ant脚本中imports一样,Spring的import元素对于模块化bean的装配非常有用,例如:<beans><import resource="billingServices.xml"/><import resource="shippingServices.xml"/><bean id="orderService"class="com.lizjason.spring.OrderService"/><beans>然而,比起在XML中用imports预装配这些bean,利用ApplicationContext来配置它们将更加灵活,也可以使XML配置更加的易于管理。
你可以像下面这样传递一个bean定义数组到ApplicationContext的构造函数中:String[] serviceResources ={"orderServices.xml","billingServices.xml","shippingServices.xml"};ApplicationContext orderServiceContext = newClassPathXmlApplicationContext(serviceResources);7.用id来标识bean你可以用id 或名字作为bean的标识。
用id可读性较差,但是它可以影响XML分析器使bean的reference有效。
如果id由于XML IDREF约束而无法使用,你可以用name作为bean 的标识。
XML IDREF约束是指id必须以字母开始(或者是在XML声名了的一个标点符号),后面可以是字母,数字,连字符,下划线,冒号或full stops(不知道怎么翻译好)。
在实际应用中很少会遇到XML IDREF约束问题。
8.在开发阶段使用依赖检查你可以为bean的dependency-check属性设置一个值来取代默认的none,比如说simple,objects 或者all,这样的话容器将替你做依赖有效性的检查。
当一个bean的所有属性(或者某些属性目录)都被明确设置,或利用自动装配时将会非常有用。
<bean id="orderService"class="com.lizjason.spring.OrderService"dependency-check="objects"><property name="companyName"value="lizjason"/><constructor-arg ref="orderDAO"/></bean>在这个例子中,容器将确保这些属性不是privitives或者保证collections是为orderService bean 设置的。