Configuration with Spring

As a little milestone in the “Variations” project I’ll introduce Spring as a configuration and dependency injection framework, inversion of control container and so on — after the big part Liquibase.

I will not give a full stack introduction to Spring. I suggest you to read a book in this topic, there are many good introductory and pro books about Spring on the market. If you want to have an application quickly up and running search between the guides on Spring (take a closer look at Spring Boot).

 A brief introduction to the Spring Stack

The Spring Framework is stack based. The base is the Spring Core which includes the core features of Spring which are used by other modules to get implement the needed functionality. Or as the Spring website states:

Core support for dependency injection, transaction management, web applications, data access, messaging, testing and more.

And in the Variations article series I’ll use a bunch of the available Feature Stack. For example dependency injection, transaction management, data access (with Hibernate, and without Hibernate; NoSQL), internalization (i18n), aspect oriented programming (AOP, with AspectJ), security, MVC and so on. Bits and pieces to get an application running — a standalone or web based one.

Why Spring

I have to tell you why I’ve chosen Spring into the Variations application. There are two main reasons. First of all: I know Spring, I’m working with Spring since 2007 and I know the pros and cons for this framework. The second is the architecture. To choose a framework on which your application is based is not a design question, it is architecture. Because architecture has a big influence on your application and your agility. I thought about at the beginning to write an application where I can change parts (DI container, GUI, back-end and so on) as I like but this approach would tie my hands in some concepts I want to apply. Naturally you, me, everyone can implement an application where the DI container is changeable on demand (writing JSR-330 compatible code) but this removes your flexibility.

I mentioned architecture decision before. Architecture defines building blocks which are hard to remove or change if you started to implement your application (and it’s harder if you are almost done). Neal Ford had a good node on this topic at the W-JAX 2013. So I had to make this decision because this app will be simple but big because I try to make it contain design blocks which are changeable: persistence layer (Database and ORM-tool), GUI. Eventual other services if I find a scenario to use them (AOP, message queues and so on).

This is why I’ve chosen Spring. It makes my life easier and you’ll get more updates more frequently because I do not have to fight with not-working dependencies. And besides this Spring has a good feature stack and I can give you a second option for some tools you’re using to change it to Spring.

Configuration

The easiest way to configure Spring is… It depends what you’re used to. However one best practice: choose one configuration model in your project and stick to it. Do not mix and mess around. It is not healthy!

I prefer however XML based configuration. So I can see in one file what is configured and I do not have to look at classes to figure out what factories and what configuration do I have. You could mix around with field injection to have less setters or constructor arguments but as mentioned before one configuration is always better than a mix of all.

There are many types of injection: constructor, setter or even field injection. There are pros and cons by each one — but it is another article to get the most out of this topic.

DI

As mentioned in the Configuration part, dependency injection is the core feature of Spring. It let’s you easily add beans to your configuration and maintain them where you need them. Often it is referred as the Hollywood principle: “Don’t call us, we call you!”

As a simple example you can (and eventually should) combine DI with coding to interfaces: you have an interface which method’s you want to use in your code. You won’t concern the implementation of the interface you just want that method (or methods) executed. The implementation can vary among your customers so you would change the behavior according to your actual project — but how do you manage which implementation to get?

You could use a factory which knows which customer is currently “running” and has eventually some if statements in its decider method. But you could use injection and inject the right implementation where you need the class. This is straightforward and this does DI. Besides this Spring does some management of the injected objects too — it knows which objects do exist, which are needed and which have to be created at every injection (prototype scope).

As stated in the Configuration section there are some possibilities to inject code — and I’ll explain my PoV in the next article which I recommend to use and why.

AOP

Spring provides AOP-Alliance compatible implementation of the aspect oriented programming paradigm. You get tools to write code interceptors for modifying method invocations or to write simply loggers or performance measure tools.

You can ask the following question: “Why would I intercept and modify method calls?” This is always a good question but sometimes your hands are tied in providing a solution: for example working with a thirdparty library or legacy code where you cannot modify the sourcecode to do exactly what you want it to do (for example omit only one specific method call because the requirements changed). Or you don’t want your developer think about the constraints of the underlying database and let them provide simple code (such a problem did I explain in a previous article). These are good scenarios for AOP.

However discussing the whole paradigm is out of the topic of this article, I’ll come back to it later.

Adding Spring to the project

OK after a look-out on dependency injection and aspect oriented programming let’s get out focus back to Spring configuration.

I added Spring to my project in the previous article but I think it won’t be bad to mention it again.

If you want to use any Spring module you have to import Spring’s core to your pom.xml. After this, you can import other modules. One point is the version-tracking. If you use multiple modules and want to be up-to date with the releases of Spring (or any other maven dependency) you will see that keeping the version numbers in the dependencies itself is error prone. But as a good message: there is always a solution. In this case we have two options: version numbering as properties and Bill of Materials — and I would combine both.

Version numbering as properties

Keeping your versions as properties is a good thing, I recommend using this approach for every dependency you have to see all versions at glance.

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-version>4.0.3.RELEASE</spring-version>
    <hibernate-version>4.3.4.Final</hibernate-version>
    <liquibase-version>2.0.5</liquibase-version>
    <commons-version>3.3.1</commons-version>
    <h2-version>1.3.175</h2-version>

    <testng-version>6.1.1</testng-version>
    <mockito-version>1.8.4</mockito-version>
</properties>

So you can write your dependency versions with the reference on the properties defined by you.

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>${commons-version}</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>${h2-version}</version>
    </dependency>
    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
        <version>${liquibase-version}</version>
    </dependency>
...

Bill of Materials (BoM)

If not yet already you’ll encounter the problem of using third party software which requires the same dependencies as your application — in our case Spring. And naturally you’ll find distributions with other versions of Spring (older or newer) and then you have version mismatch. And version mismatch can result in various errors or side-effects compile time (happier case) or runtime (worst case). But the Maven BoM (Bill of Materials) gives a solution to this problem.

A BoM dependency keeps track of version numbers and ensures that all dependencies (both direct and transitive) are at the same version.

So if you use Spring 4.0.3.RELEASE (as I currently do in Variations) you can add the dependency of the BoM into your pom.xml to handle other versions. As example the snippet from the Variations’ pom.xml:

<dependencyManagement>
    <dependencies>
       <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>${spring-version}</version>
            <type>pom</type>
            <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>

And you can write the Spring dependencies without any reference on the version number (nor hard coded nor with properties):

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
</dependency>

And as a reminder I’ll show the injection and configuration for Liquibase as done in the previous article.

<bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
    <property name="dataSource" ref="dataSource" />
    <property name="changeLog" value="classpath:dbchange/master.xml" />
</bean>

A look out

After this session I think I should finish the configuration introduction — later it’ll come again and again as I add dependencies and beans to the application.

In the next article I’ll write some (more) words about dependency injection and which type I suggest to use and why.  There are books and other articles about DI with Spring so do not expect a full documentation — I’ll restrict the article to my point of view.

Advertisements

One thought on “Configuration with Spring

  1. Pingback: Dependency Injection with Spring | HaHaMo Group

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s