知道美河 | 上传资料 | VIP申请 | 精品课程 | 资料搜索 | 问题反馈 | 会员手册 | 积分消费 | 积分充值 | 帐号保护
美河学习学习在线赞助VIP

美河学习在线(主站) eimhe.com

 找回密码
 建立账号
查看: 5091|回复: 0

[转帖] 转来一个Spring的文章

[复制链接]
发表于 2007-6-2 09:43:29 | 显示全部楼层 |阅读模式
这里是一篇关于如何写Spring的XML文件的文章。老外写的直接转过来了。呵呵。。
老外写的文章不会用太复杂的单词,建议大家开着金山词霸就可以理解了。

Twelve Best Practices For Spring XML Configurations
by Jason Zhicheng Li
01/25/2006

Spring is a powerful Java application framework, used in a wide range of Java

applications. It provides enterprise services to Plain Old Java Objects (POJOs). Spring

uses dependency injection to achieve simplification and increase testability. Spring

beans, dependencies, and the services needed by beans are specified in configuration

files, which are typically in an XML format. The XML configuration files, however, are

verbose and unwieldy. They can become hard to read and manage when you are working on a

large project where many Spring beans are defined.

In this article, I will show you 12 best practices for Spring XML configurations. Some of

them are more necessary practices than best practices. Note that other factors, such as

domain model design, can impact the XML configuration, but this article focuses on the XML

configuration's readability and manageability.
1. Avoid using autowiring

Spring can autowire dependencies through introspection of the bean classes so that you do

not have to explicitly specify the bean properties or constructor arguments. Bean

properties can be autowired either by property names or matching types. Constructor

arguments can be autowired by matching types. You can even specify the autodetect

autowiring mode, which lets Spring choose an appropriate mechanism. As an example,

consider the following:

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

The property names of the OrderService class are used to match a bean instance in the

container. Autowiring can potentially save some typing and reduce clutter. However, you

should not use it in real-world projects because it sacrifices the explicitness and

maintainability of the configurations. Many tutorials and presentations tout autowiring as

a cool feature in Spring without mentioning this implication. In my opinion, like object-

pooling in Spring, it is more a marketing feature. It seems like a good idea to make the

XML configuration file smaller, but this will actually increase the complexity down the

road, especially when you are working on a large project where many beans are defined.

Spring allows you mix autowiring and explicit wiring, but the inconsistency will make the

XML configurations even more confusing.
2. Use naming conventions

This is the same philosophy as for Java code. Using clear, descriptive, and consistent

name conventions across the project is very helpful for developers to understand the XML

configurations. For bean ID, for example, you can follow the Java class field name

convention. The bean ID for an instance of OrderServiceDAO would be orderServiceDAO.For

large projects, you can add the package name as the prefix of the bean ID.
3. Use shortcut forms

The shortcut form is less verbose, since it moves property values and references from

child elements into attributes. For example, the following:

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

can be rewritten in the shortcut form as:

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

The shortcut form has been available since version 1.2. Note that there is no shortcut

form for <ref local="...">.

The shortcut form not only saves you some typing, but also makes the XML configuration

files less cluttered. It can noticeably improve readability when many beans are defined in

a configuration file.
4. Prefer type over index for constructor argument matching

Spring allows you to use a zero-based index to solve the ambiguity problem when a

constructor has more than one arguments of the same type, or value tags are used. For

example, instead of:

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

It is better to use the type attribute like this:

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

Using index is somewhat less verbose, but it is more error-prone and hard to read compared

to using the type attribute. You should only use index when there is an ambiguity problem

in the constructor arguments.
5. Reuse bean definitions, if possible

Spring offers an inheritance-like mechanism to reduce the duplication of configuration

information and make the XML configuration simpler. A child bean definition can inherit

configuration information from its parent bean, which essentially serves as a template for

the child beans. This is a must-use feature for large projects. All you need to do is to

specify abstract=true for the parent bean, and the parent reference in the child bean. For

example:

    <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>

The shippingService bean inherits the value lizjason for the companyName property from the

abstractService bean. Note that if you do not specify a class or factory method for a bean

definition, the bean is implicitly abstract.
6. Prefer assembling bean definitions through ApplicationContext over imports

Like imports in Ant scripts, Spring import elements are useful for assembling modularized

bean definitions. For example:

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

However, instead of pre-assembling them in the XML configurations using imports, it is

more flexible to configure them through the ApplicationContext. Using ApplicationContext

also makes the XML configurations easy to manage. You can pass an array of bean

definitions to the ApplicationContext constructor as follows:

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

       

7. Use ids as bean identifiers

You can specify either an id or name as the bean identifier. Using ids will not increase

readability, but it can leverage the XML parser to validate the bean references. If ids

cannot be used due to XML IDREF constraints, you can use names as the bean identifiers.

The issue with XML IDREF constraints is that the id must begin with a letter (or one of a

few punctuation characters defined in the XML specification) followed by letters, digits,

hyphens, underscores, colons, or full stops. In reality, it is very rare to run into the

XML IDREF constraint problem.
8. Use dependency-check at the development phase

You can set the dependency-check attribute on a bean definition to a value other than the

default none, such as simple, objects, or all, so that the container can do the dependency

validation for you. It is useful when all of the properties (or certain categories of

properties) of a bean must be set explicitly, or via autowiring.

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

In this example, the container will ensure that properties that are not primitives or

collections are set for the orderService bean. It is possible to enable the default

dependency check for all of the beans, but this feature is rarely used because there can

be beans with properties that don't need to be set.
9. Add a header comment to each configuration file

It is preferred to use descriptive ids and names instead of inline comments in the XML

configuration files. In addition, it is helpful to add a configuration file header, which

summarizes the beans defined in the file. Alternatively, you can add descriptions to the

description element. For example:

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

One advantage of using the description element is that it is easy to for tools to pick up

the description from this element.
10. Communicate with team members for changes

When you are refactoring Java source code, you need to make sure to update the

configuration files accordingly and notify team members. The XML configurations are still

code, and they are critical parts of the application, but they are hard to read and

maintain. Most of the time, you need to read both the XML configurations and Java source

code to figure out what is going on.
11. Prefer setter injection over constructor injection

Spring provides three types of dependency injection: constructor injection, setter

injection, and method injection. Typically we only use the first two types.

    <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>

In this example, the orderService bean uses constructor injection, while the

BillingService bean uses setter injection. Constructor injection can ensure that a bean

cannot be constructed in an invalid state, but setter injection is more flexible and

manageable, especially when the class has multiple properties and some of them are

optional.
12. Do not abuse dependency injection

As the last point, Spring ApplicationContext can create Java objects for you, but not all

Java objects should be created through dependency injection. As an example, domain objects

should not be created through ApplicationContext. Spring is an excellent framework, but,

as far as the readability and manageability are concerned, the XML-based configuration can

become an issue when many beans are defined. Overuse of dependency injection will make the

XML configuration more complicated and bloated. Remember, with powerful IDEs, such as

Eclipse and IntelliJ, Java code is much easier to read, maintain, and manage than XML

files!
Conclusion

XML is the prevailing format for Spring configurations. XML-based configuration can become

verbose and unwieldy when many beans are defined. Spring provides a rich set of

configuration options. Appropriately using some of the options can make the XML

configurations less cluttered, but other options, like autowiring, may reduce readability

and maintainability. Following good practices discussed in the article may help you to

create clean and readable XML configuration files!


[ 本帖最后由 adamed 于 2007-6-2 09:44 编辑 ]
您需要登录后才可以回帖 登录 | 建立账号

本版积分规则

 
QQ在线咨询

QQ|小黑屋|手机版|Archiver|美河学习在线 ( 浙网备33020302000026号 )

GMT+8, 2025-5-23 13:34

Powered by Discuz!

© 2001-2025 eimhe.com.

快速回复 返回顶部 返回列表