您的位置:首页 > 编程语言 > Java开发

转 Twelve Best Practices For Spring XML Configurations

2008-06-05 22:03 609 查看

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="...">
.

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
id
s as bean identifiers

You can specify either an
id
or
name
as the bean identifier. Using
id
s will not increase readability, but it can leverage the XML parser to validate the bean references. If
id
s cannot be used due to XML IDREF constraints, you can use
name
s 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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: