Spring dependency injection example

19 December 2012
By Gonçalo Marques
In this tutorial you will learn how to use Spring dependency injection (or inversion of control) feature.

Used software and configuration

This tutorial considers the following software and environment:

  1. Ubuntu 12.04
  2. Maven 3.0.4
  3. JDK 1.7.0.09
  4. Spring 3.2.0

Configure Maven to get the required Spring dependencies:

Maven pom.xml file referencing Spring dependencies
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.byteslounge.spring</groupId>
  <artifactId>com-byteslounge-spring</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>com-byteslounge-spring</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- Define Spring version as a constant -->
    <spring.version>3.2.0.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
  </dependencies>
</project>

Now place yourself in the project directory and issue the following command to prepare your project for Eclipse:

mvn eclipse:eclipse

After conclusion you can import the project into Eclipse.

Spring dependency injection overview

One of most powerful Spring features is the Dependency Injection (DI) or otherwise called Inversion of Control (IoC) mechanism. The Spring container is capable of fetching a managed bean and inject that bean into another managed bean. Usually the application developer defines a Java interface and then declares a property in a managed bean which type is the same of that interface. When the Spring container initializes the bean it will automatically fetch an implementation of that interface and inject into the bean, i.e. the bean has a dependency that is injected during initialization time. This way the target bean becomes completely decoupled from the bean that is injected, i.e. the implementation of the interface can be switched by another implementation without changing any single piece of code in the target bean. The interface implementation itself must also be a Spring managed bean, but let's see it in practice.

Preparing the injected bean

First we define the interface of the injected bean:

Injected bean interface
package com.byteslounge.spring;

public interface InjectedBean {

  void doSomething();
	
}

Now we define the implementation:

Injected bean implementation
package com.byteslounge.spring;

import org.springframework.stereotype.Service;

@Service
public class InjectedBeanImpl implements InjectedBean {

  @Override
  public void doSomething() {
    System.out.println("Bean was correctly injected!");
  }

}

Note the @Service annotation. This tells the Spring container that this class is a managed bean. When the Spring container scans this package for beans during container initialization it will know that this class represents a managed bean.

Defining the target bean

Now we define a simple Spring bean that will receive the injected bean as a dependency:

The target Spring bean

package com.byteslounge.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ExampleBean {

  @Autowired
  private InjectedBean injectedBean;

    public void callExampleMethod() {
      injectedBean.doSomething();
    }

}

Note the injectedBean bean property defined as InjectedBean type. The used type here is the interface type. We should also note that this property is annotated with @Autowired annotation. This means that when the Spring container initializes this bean it will lookup for an implementation of this interface type and inject it as a property of this bean! This is actually the Spring Dependency Injection mechanism. You can easily see that the injected bean and the target bean became decoupled. You can switch the injected bean implementation without changing a single line of code in the target bean.

The Main application class

Our Main class looks like the following:

Main class
package com.byteslounge.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main 
{
  public static void main( String[] args )
  {
    ApplicationContext ctx = 
                  new ClassPathXmlApplicationContext("spring.xml");
    ExampleBean exampleBean = (ExampleBean) ctx.getBean("exampleBean");
    exampleBean.callExampleMethod();
  }
}

As we have already seen in previous Spring tutorials on this website we are simply initializing the Spring container from spring.xml configuration file. Then we fetch exampleBean bean from the container and call its callExampleMethod() method.

Spring configuration

For this example we need to define the packages where the Spring container should look for beans (the classes annotated with @Service annotation from the previous tutorial sections):

spring.xml configuration file
<?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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    <context:component-scan base-package="com.byteslounge.spring" />
    
</beans>

Running the application

When we run the application the following output will be generated:

Bean was correctly injected!

InjectedBean was injected into ExampleBean and doSomething() method from the injected bean was successfully called. This tutorial's source code is available for download at the bottom of this page.

Download source code from this article

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: https://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: