Inversion of Control with Spring

async loader

What is Spring?

Spring is an Inversion of Control (IoC) container, which means it uses Dependency Injection (DI) to provide dependencies to classes. For example, let’s say we have a class EventService that has a dependency on a Data Access Object (DAO). Here’s EventService without an IoC container:

public class EventService {
    private EventDao eventDao;
    
    public EventService() {
        eventDao = new EventDaoImpl();
        eventDao.setDataSource(...);
        ...
    }
}

Here’s EventService with an IoC container:

public class EventService {
    @Autowire
    private EventDao eventDao;
}

Note that we do not have to know anything about EventDao or its dependencies. Instead, the @Autowire annotation notifies the IoC container to provide EventService with an EventDao (which has an @Component annotation) at runtime. Alternatively, you can use XML:

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

    <bean id="eventService" class="trey.service.EventServiceImpl">
        <property name="eventDao" ref="eventDao" />
        <property name="customerService" ref="customerService" />
        <property name="jmsTemplate" ref="jmsTemplate" />
        <property name="processingQueue" ref="processingQueue" />
    </bean>

    <bean id="eventDao" class="trey.dao.EventDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>
    ...
</beans>

Why Spring?

This separation of concerns promotes strong interfaces. Per best practices, EventDao is an interface that can have any number of implementations. For example, we could have database vendor specific sub-classes, such as EventDaoOracle and an EventDaoMysql, where each sub-class would encapsulate the different syntaxes to accomplish the same task. While many projects have only a single sub-class (commonly called EventDaoImpl), the flexibility provided by the separation of concerns is very powerful.
Strong interfaces also promote testability via frameworks such as EasyMock and Mockito. For example, you could use Mockito to create a mock EventDao that you can then be injected into EventService to write unit tests that do not rely on a database.

Another reason to use Spring is for declarative transaction management, which eliminates boilerplate code to explicitly start/end transactions. Basically, instead of explicitly managing transactions in the code you can provide an annotation to indicate that a method’s contents must be executed within a transaction. See this example.
Spring offers tools at all tiers of the technology stack. Here are some them:

  • Web Tier: Spring Web Services, Spring MVC, Spring Webflow, Spring Security
  • Database Tier: Spring JDBC Template
  • Messaging Tier: Spring JMS Template
  • Enterprise Integration Patterns: Spring Integration

You can cherry pick the ones you want or you could even build an application that uses Spring for every tier. They’re all built on Spring Core, which is the base IoC that glues them together. In fact, some non-Spring tools support configuration/integration with Spring, such as Apache Camel.

Need another reason to learn Spring? Spring jobs are now in higher demand than J2EE and EJB: