Gordon Dickens is an instructor, mentor & consultant. Gordon is currently architecting and teaching several official SpringSource courses and actively tweets about open source technology at http://twitter.com/gdickens. Gordon is active within the Spring Framework community focussed on: Spring training, Spring Roo, Spring Integration, Spring Batch and Eclipse Virgo OSGi projects. Gordon is a DZone MVB and is not an employee of DZone and has posted 39 posts at DZone. You can read more from them at their website. View Full User Profile

Enterprise Spring Framework Best Practices – Part 3 – XML Config

08.09.2012
| 7485 views |
  • submit to reddit

The best thing about Spring is that there are several ways to solve a problem. The worst thing about Spring is that there are several ways to solve a problem!

One of the greatest challenges when using Spring is choosing the best way to implement solutions. As most of us developers do, we hit Google or grab books on Spring. That can get us moving in the right direction. Many times we find conflicting configurations between implementation approaches. For Spring newcomers, this can be challenging and can cause grievous mental confusion down the road.

Spring Namespaces

We have no version numbers in schema references.

Instead of:

<?xml ?>
<beans >
...
</beans>

USE This Config:

<?xml ?>
<beans >
...
</beans>

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



One Bootstrap XML File


A myriad of examples of use multiple XML configuration files. An application usually has several XML configuration files, but there should only be ONE bootstrap file. This bootstrap file should use the <import /> to include other config files.



Classpath Prefix


Always use classpath: prefix
When importing resources, XML config, properties, etc., always use the classpath: or the classpath*: prefix.
This provides consistency and clarity to the location of the resource. Not every feature of Spring behaves the same way, and 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.

Example:

<import />



Bean Naming


The Spring Context is the container for the application’s beans. Each bean is uniquely identified by its name. The XML attribute “id” is most commonly used to define the bean’s name. The “id” attribute is great because it is, by XML Law, unique per file.
<bean id="accountService" class="com.gordondickens.services.AccountService/>

However, if we want to use special symbols in the name or provide aliases to the name, we can use the Spring provided “name” attribute.

<bean class="com.gordondickens.services.AccountService/>

Spring 3.1 added the profile feature, providing the ability to configure beans by category or region.
With 3.1, Spring overloads the XML “id” attribute, allowing multiple beans with the same “id” in an XML file by profile.

<?xml ?>
<beans > <beans > <bean id="dataSource" class="..."/> <bean id="messagingProvider" class="..."/> </beans> <beans > <bean id="dataSource" class="..."/> <bean id="messagingProvider" class="..."/> </beans>
</beans>

For more detail on Spring 3.1 profiles, see my blog Spring 3.1 Environment Profiles



Dependency Injection


Dependency Injection is one of the basic tenets of the Spring Framework. DI provides developers the ability to “wire together” bean relationships in configuration instead of coding the relationships.

The two ways to perform DI are either by Constructor Injection or Setter Injection.

Enterprise Spring Best Practices – Part 2 – Application Architecture describes the layered application approach. In this layered approach, we can expect to inject beans together between layers.
For example, wiring from the bottom up:

  1. DataSource, the common JDBC class for database connectivity, is injected into our persistence beans
  2. The persistence beans are injected into our service beans
  3. The service beans are injected into our controller beans

Constructor Injection

Constructor injection is performed using the <bean/> node <constructor-arg.
Thread safety is a strong case for using constructors. Making beans immutable is the cheapest thread safety we can code.

In the following example, we see configuration of an in-memory HSQLDB database with an “id” of “dataSource.” The bean AccountRepositoryImpl is injected with this implementation when Spring starts.

<bean id="accountRepository" class="com.gordondickens.repository.internal.AccountRepositoryImpl"> <constructor-arg />
</bean> <!-- Spring's In-Memory DB Config, using HSQLDB -->
<!-- Note the HSQLDB driver must be in the project dependencies -->
<jdbc:embedded-database id="dataSource" > <jdbc:script /> <jdbc:script />
</jdbc:embedded-database>

Setter Injection

Setter injection provides the capability of injecting beans via a setter method. Traditionally, this has been the preferred choice for many developers because the configuration is easier to read.

<bean id="accountRepository" class="com.gordondickens.repository.internal.AccountRepositoryImpl"> <property />
</bean>



Third-Party Beans


Any Java class can be used in the Spring framework. Infrastructure beans, such as ActiveMQ’s ConnectionFactory or Oracle’s OracleDataSource is possible.

With third-party beans, where we don’t have the source, or do not wish to tamper with the source, the choice for DI is made for us.



Externalize Properties


Deployment configuration requires setting environmental parameters, such as database connection properties.

Since XML can be brittle, it is best to externalize settings into property files. This makes it easier for the deployment team to change resource configuration with less risk.

Spring provides a PropertyPlaceholderConfigurer for that purpose.

Property Replacement Config

<context:property-placeholder /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property /> <property /> <property /> <property />
</bean>

Properties File

\:hsqldb\:mem\:mydb database.password=



Logging Beans


Check out Enterprise Spring Best Practices – Part 1 – Project Configuration for logging configuration.

Java Util Logging

To Enable handling of java.util.logging classes with SLF4J. Register the following in your Spring configuration:

<!-- Enable handling of java.util.logging through SLF4J -->
<bean id="slf4JBridgeHandler" class="org.slf4j.bridge.SLF4JBridgeHandler" />
<bean class="org.slf4j.bridge.SLF4JBridgeHandler" />

System.out and System.err

To Enable handling of System.out and System.err messages, register the following in your Spring configuration:

NOTE: This is NOT recommended for ongoing development, but it is for migrating poor code to use logging.

<!-- System.out.println & System.err.println handling through SLF4J -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property /> <property /> <property > <list> <!-- Set log level for System.out --> <util:constant /> <!-- Set log level for System.err --> <util:constant /> </list> </property>
</bean>

Maven Dependency for SysOutOverSLF4J

<dependency> <groupId>uk.org.lidalia</groupId> <artifactId>sysout-over-slf4j</artifactId> <version>1.0.2</version>
</dependency>



Best Practices

  • DO NOT use version numbers with the Spring schema namespaces
  • Always use the classpath:/ prefix for consist-resource referencing
  • Always use a single XML config file to bootstrap the application or tests
  • Use the XML “id” attribute to identify a bean
  • Use Constructor injection to promote thread safety
  • Use Properties for configurable resources
  • DO NOT use the SysOutOverSLF4J for anything other than migration
Published at DZone with permission of Gordon Dickens, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Jakub Kubrynski replied on Fri, 2012/08/10 - 2:32am

Looking at these namespaces (with and without versions), I feel that they are too similar ;)

Harald Wellmann replied on Fri, 2012/08/10 - 10:38am

The best thing about Spring 3.1 is that you can ditch XML configuration and work with 100% Java configuration instead.

Bob Winters replied on Fri, 2012/08/10 - 10:29pm

I recommend the author go read about @Autowired :)

Charlie Mordant replied on Mon, 2012/08/13 - 3:14am

@Bob

XML conf allow you to do more things than @Autowired and other annotations-class-based annotations.

For example when you deal with JPA, you can make two different orm.xml with two different persistence unit where on one side an attribute is mapped in database (let's take the example of a user and he's Authority in a security db schema) and in the other side marked as transient (because in your business db, you don't want to have to deal with security data).

 Same apply with Spring. Pure Java config is good too (Spring 3.1), but is too verbose (IMHO), and I don't think that's a good thing to mix configuration with code (do you put your configuration in the src/main/java folder? What's the convention to recognognize a java configuration package opposed to a business one?)

 

Howhever it's nice article.

 

Charlie

 

 

Chris Falter replied on Mon, 2013/01/07 - 3:27pm

OK, I give up: just how do I implement this version number/configuration tip?

"Instead of:
<?xml ?>
<beans >
...
</beans>

"USE This Config:
<?xml ?>
<beans >
...
</beans>

I suspect an editing error.

Brice Giesbrecht replied on Wed, 2013/11/06 - 8:39am in response to: Chris Falter

Yes it is. Check out this same post on Gordon's blog for the snippets.

http://gordondickens.com/wordpress/2012/07/30/enterprise-spring-framework-best-practices-part-3-xml-config/

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.