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

15 thoughts on “13 best practices for writing spring configuration files”

  1. You can write an entire Spring application without any XML at all! Take a look at the @Configuration and @Bean annotations, which allow you to programmatically create your Beans in Java. The use of XML has been discouraged (or at least played down) by the Spring folks for a few years already.

    1. Hi Will, Thanks for your time to express your thoughts. I believe that use of xml vs annotations has become more of a personal choice for smaller projects. For large projects, though it’s possible as you say to write everything in annotations, but should be avoided to loosely couple your sourcecode with any dependency.

  2. Hi Lokesh,

    I have been working in Spring.But I cant understand that in our framework we havnt used any injection’s and we are doing all our work throug @autowire functionalty.We are not using any constructor or setter injection.Is it possible?

  3. 13) Do not abuse/overuse dependency injection
    Can you give example on the above bullet ? Code example would be much appreciated ! Thank you !

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

  5. “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. 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.

      1. If your class requires that many dependencies, then it is suggesting that your class is doing too much. Gervais is right – it should never be possible to instantiate your object in an invalid state. So, instead of resorting to setter injection because of the number of classes that need injecting, your should consider splitting your class up into several smaller classes that only require a small number of dependencies so that they can all be passed to the constructor.

  6. 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!

Note:- In comment box, please put your code inside [java] ... [/java] OR [xml] ... [/xml] tags otherwise it may not appear as intended.

Leave a Reply

Your email address will not be published. Required fields are marked *


three + 8 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>