Java程序员必须掌握Spring XML配置的12个技巧

Spring是一个强有力的Java程序框架,其被普遍应用于Java的程序中。它用POJO提供了企业级服务。Spring利用依赖注入能够得到简单而有效的测试能力。Spring beans,依赖关系,以及服务所须要的bean都将在配置文件中予以描述,配置文件通常采用XML格式。然而XML配置文件冗长而不易使用,在你进行一个使用了大量bean的大项目中它将变得难以阅读和控制。java

在这篇文章中我将给你展现12种的有关Spring XML配置文件的最佳技巧。它们中的一些具备更多的实际意义,而不只是最好的技巧。请注意另一些因素,例如域模型的设计,会影响到XML配置,可是这篇文章更关注于XML配置的可读性和可操控性。spring

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配置更加的使人费解。ide

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="java.lang.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将会默认为abstract

6. 尽可能使用ApplicationContext装配bean,而不是用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 = new ClassPathXmlApplicationContext(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设置的。为全部的bean设置默认的依赖检查是可能的,但这个特性因为有些bean的属性不须要设置而不多使用。

9. 为每一个配置文件加一个描述注释

在XML配置文件中最好使用有描述性的id和name,而不是成堆的注释。另外,加一个文件描述头将会很是有用,这个描述能够归纳文件中定义的bean。另外一个选择,你能够在description元素中加入描述信息。例如:

<beans>
        <description> This file defines billing service related beans and it depends on baseServices.xml,which provides service bean templates... </description> ... </beans>

用description元素的一个好处就是工具能够很容易的把描述信息从这个元素中提取出来。

10. 和team members沟通变动

当你修改java源码后,要确保更改了配置文件中的相应部分并把这个状况告知你的team members。XML配置文件也是代码,它们是程序的重要组成部分,但它们很难阅读和维护。大多数时间里,你须要同时看XML配置文件和java代码才能知道是怎么回事。

11. setter注入和构造函数注入,优先使用前者

Spring提供了三种注入方式:构造函数注入,setter注入和方法注入。通常咱们使用前两种。

<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 bean用了构造函数注入,而BillingService bean用了setter注入。构造函数注入能够确保bean正确地构建,可是setter注入更加的灵活和易于控制,特别是当class有多个属性而且它们中的一些是可选的状况是更是如此。

12. 不要滥用注入

就像前面提到的,Spring的ApplicationContext能够替你建立java对象,但不是全部的java对象都应该经过注入建立。例如,域对象就不该该经过ApplicationContext建立。Spring是一个优秀的框架,可是考虑到可读性和可操控性,基于XML配置的配置会在定义不少bean的时候出现麻烦。过渡使用依赖注入将会使XML配置更加的复杂和冗长。切记,当使用高效的IDE时,例如Eclipse and IntelliJ,java代码更加的易于阅读,维护和管理比使XML文件

结论

XML是Spring流行的配置格式。存在大量bean定义时,基于XML的配置会变得冗长而不易使用。Spring提供了丰富的配置选项。适当地使用这些选项可使XML配置更加的清晰,但其它的一些选项,例如自动装配,可能会下降可读性和可维护性。参考本文中提到的这些技巧可能会帮助你建立干净而易读的XML配置文件。

苏先生ii:专一于Java开发技术的研究与知识分享!

————END————

 

相关文章
相关标签/搜索