13 best practices for writing spring configuration files

Spring is a powerful Java application framework, used in a wide range of configuration options. Its best feature if that it provides enterprise services to Plain Old Java Objects (POJOs) called beans. Spring uses dependency injection (DI) to achieve simplification and increased testability. Spring beans, dependencies, and the services needed by beans are specified in xml configuration files or annotations. The XML configuration files, however, are verbose and more clean. If not planned and written correctly, it becomes very hard to manage in big projects.

In this article, I will show you 10 best practices for writing spring XML configurations. Some of them may seem more necessary practices rather than best practices, yet I have included them in here because they were highly related to the topic.

Note: Some other factors, such as application design, can impact the XML configuration decisions but I am focusing on the XML configuration’s readability and manageability only.
1) Add a header comment to each configuration file
2) Use consistent naming conventions
3) No version numbers in schema references
4) Prefer setter injection over constructor injection
5) Prefer type over index for constructor argument matching
6) Use shortcut forms over expanded forms
7) Reuse bean definitions as much as possible
8) Always use ids as bean identifiers
9) Try to avoid autowiring
10) Always use classpath prefix
11) Always externalize properties
12) Use dependency-check at the development phase
13) Do not abuse/overuse dependency injection

Lets discuss each of above in detail to make more sense.

1) Add a header comment to each configuration file

I always put more stress on code comments. The same goes for configuration files also. It is always very helpful to add a configuration file header, which summarizes the beans/properties defined in the configuration files.

In spring configuration, you can add comments as adding xml comments or you can use the description element. For example:

<beans>
	<description>
		This configuration file will have all beans 
		which may be used for controlling transactions.
	</description>
	...
</beans>

One possible advantage of using the description tag is that some tools may pick up the description from this element to help you in other places.

2) Use consistent naming conventions

This is very important thing that you use same naming across all configuration files. Using clear, descriptive, and consistent name conventions across the project increase the readability of configuration files and make it easy for other developers to avoid some accidental bugs.

For bean ID, for example, you can follow the Java class field name convention. The bean ID for an instance of EmployeeUpdateDAO would be employeeUpdateDAO. For large projects, you can add the package name as the prefix of the bean ID. e.g. finance.employeeUpdateDAO.

3) No version numbers in schema references

I have also pointed out this feature earlier in previous post. I am again including it because it is essential and beneficial in long term specially to reduce maintainbility. To refresh your memory, specifying version number in bean configuration files for referenced schemas are not mandatory at all, and you can omit it. If fact, you should omit it all the time.

Spring automatically picks the highest version available from the project dependencies (jars). Also, as the project evolves and the Spring version will be updated, we won’t have to maintain all the XML config files to see the new features.

Read More: Do not specify version numbers in Spring schema references

A sample example will be like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context.xsd">

  <!-- Other bean definitions-->
   
</beans>

4) Prefer setter injection over constructor injection

Spring provides three types of dependency injection: constructor injection, setter injection, and method injection. Usually, we all use first two types only.

<!-- Constructor injection -->
<bean id="employeeDAO"	class="com.howtodoinjava.dao.EmployeeDAO">
	<constructor-arg ref="datasource"/>
</bean>

<!-- Setter injection -->
<bean id="employeeDAO" class="com.howtodoinjava.dao.EmployeeDAO">
	<property name="datasource"	ref="datasource">
</bean>

Constructor injection can provide the cheapest thread safety possible i.e. immutable object. Also it guarantees that object will not be handed over to other beans without complete initialization.

Setter injection provides much desired capability i.e. flexibility or maintainability. If there are multiple attributes to set in a bean, then creating a long list of parameters to constructor is not good idea. Also, if is possible that some of the attributes might be optional.

Prefer flexibility. For immutability or thread safety, follow other programming rules.

Read More: How to make a java class immutable

5) Prefer type over index for constructor argument matching in Constructor injection

Better to avoid constructor injection and prefer to use setter injection for dependency injection. But, if you have an absolute requirement to use constructor injection then always prefer parameter matching based on type rather than index.

<!-- Index based constructor injection -->
<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAO">
	<constructor-arg index="0" value="rest"/>
	<constructor-arg index="1" value="8080"/>
</bean>

<!-- Type based constructor injection -->
<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAO">
	<constructor-arg type="java.lang.String" value="rest"/>
	<constructor-arg type="int" value="8080"/>
</bean>

As you can see that type based argument passing is more readable and less error prone. But, anytime there is any ambiguity in type based argument passing, go to index based argument passing without hesitation.

6) Use shortcut forms over expanded forms

Spring bean configuration semantics allow two forms for specifying property values and other bean references. One is expanded and other is shorter form. Prefer shorter version.

<!-- Expanded version -->
<bean id="employeeDAO" class="com.howtodoinjava.dao.EmployeeDAO">
	<property name="datasource">
		<ref bean="datasource"></ref>
		<value>datasource</value>
	 </property>
</bean>

<!-- Shorter/shortcut version -->
<bean id="employeeDAO" class="com.howtodoinjava.dao.EmployeeDAO">
	<property name="datasource"	ref="datasource" value="datasource">
</bean>

7) Reuse bean definitions as much as possible

Spring provides a very useful capability which you should use extensively in your project and i.e. bean definition re-usability. Here I am not talking about bean references for setter injection. Rather I am pointing out the bean definition re-use in constructing other beans.

Take an example of datasource definition:

<bean id="abstractDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
	destroy-method="close"
	p:driverClassName="${jdbc.driverClassName}"
	p:username="${jdbc.username}"
	p:password="${jdbc.password}" />

<bean id="concreteDataSourceOne"
	parent="abstractDataSource"
	p:url="${jdbc.databaseurlOne}"/>
 
<bean id="concreteDataSourceTwo"
	parent="abstractDataSource"
	p:url="${jdbc.databaseurlTwo}"/>

Read complete configuration example here: Spring 3.2.5 AbstractRoutingDataSource example

8) Always use ids as bean identifiers

Spring allows two types of identifiers for a bean. Using attribute “id” or by “name”. You should always choose attribute id over name. Usually it does neither increase readability nor benefit any performance scenario. It is just industry standard practice which all fellow developers are following worldwide and even in your team.

Just don’t be odd man out here.

9) Try to avoid autowiring

Autowiring is a great feature if you can manage it in long term. Usually it is beneficial if you project is having very few beans and you can almost remember them all in your memory as well.

As soon as project gets bigger, autowiring starts creating trouble in identifying correct dependency to use. The main drawback, I find is not to have a overview of whole system binded together. This is where spring configuration files win. They can represent the whole system to any new guy in couple of minutes.

Also, when you start debugging some complex issues then all information present in one place in configuration files, actually helps a lot. Autowiring makes debugging harder.

Read More: Spring autowiring concepts

10) Always use classpath prefix

When importing resources, XML config, properties, etc. Always use the classpath: or classpath*: prefix. This provides consistency and clarity to the location of the resource. Not every feature of Spring behaves the same, classpath: guarantees consistency.

The classpath is determined by the build tool and IDE. Usually this is src/main/java for java code, src/main/resources for non-java dependencies and for tests, src/test/java for java code and src/test/resources for non-java resources.

<!-- Always use classpath: prefix-->
<import resource="classpath:/META-INF/spring/applicationContext-security.xml"/>

11) Always externalize properties

Often there are multiple configuration parameters related to runtime of application. They are passed to bean definitions in bean configuration context file. DO not hard code them in config file. Instead externalize them to some properties file(s).

Better group them in separate files based on their usage or module i.e. all JDBC datasource related properties in jdbc.properties file.

<bean id="abstractDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
        destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}" />

and properties file

/* file://jdbc.properties */

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=password

12) Use dependency-check at the development phase

You should mostly set the dependency-check attribute on a bean definition to simple, objects, or all (default value is none i.e. no checking), so that the container can do explicit 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="abstractDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
	destroy-method="close"
	p:driverClassName="${jdbc.driverClassName}"
	p:username="${jdbc.username}"
	p:password="${jdbc.password}" 
	dependency-check="all" />

In above given example, the container will ensure that all properties/parameters to datasource are set in application initialization time itself.

13) Do not abuse/overuse dependency injection

Finally, please do not abuse the motive behind introducing dependency injection. Java provide “new” keyword to create new objects. Use this wonderful keyword where DI is not necessary e.g. DTO objects. Don’t try to play smarter. Just follow the basics.

Drop me a comment if you feel otherwise on any of above points.

Happy Learning !!

Lokesh has written 269 articles

I have 7 Years of rich experience in java technology. This has only increased my hunger to learn more. In this blog, i will be writing on different topics occasionally, and would love to engage in some meaningful serious discussions with you folks.

9 thoughts on “13 best practices for writing spring configuration files

  1. Green Bean says:

    Nice article – except I found the same exact points from 2 different posts:
    Twelve Best Practices For Spring XML Configurations by Jason Zhicheng Li 2006
    Enterprise Spring Framework Best Practices – Part 3 – XML Config by Gordon Dickens 2012.
    While I don’t know if it is their original ideas, but It is OK to summarize best practices, but you have to give reference/credit to the source.

    1. Lokesh says:

      Hello Mr. Bean.. :-). I love the character.
      Thanks for dropping your thoughts here. I appreciate. I have not gone through above both posts if they exist somewhere. Yes, I have some of the ideas in this post recalled after searching for best practices. But, I have not used any other article/post to create content for it. If any article really looks like this, I believe it coincidence. Anyway, none of the content is original, either in my blog or in other’s blog. Original content is available only in Spring user guide and it’s java docs. Rest everything is just logs of one’s learning curve.

  2. “Prefer setter injection over constructor injection” hell nooo !

    Constructors are used to create object in usable state. They are the perfect way to indicate what is required by a “bean” to work well. And as indicated by their name they must be used to construct an object.
    It’s more elegant to create an object with a constructor than with a default constructor and a few setters.

    1. Lokesh says:

      Let me re-iterate again: “Creating a long list of parameters to constructor is not good idea. Also, if is possible that some of the attributes might be optional.”

      In fact, it is much of choice of decision as like other options. I respect your opinion but I always prefer setter injection. They never created any problem for me and provided more control for my style of code writing.

  3. Thanks a lot for this article, I always learn a lot from these articles you post! I wanted to mention a rather blaring error in the English. At the start of the article, it says “This configuration files will have all beans which may be used for controlling transactions.” Given that you are talking about “files”, rather than a single file, the sentence should be “These configuration files will have all beans which may be used for controlling transactions.” I realize this is not English class or anything like that, but propagation of this error could possibly happen with respect to readers! When I reach 7 years of experience, I hope I know just as much on the subject of Java!

Want to ask any question? Or suggest anything?