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
) 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 id
s 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