Skip to main content

Simple Spring Dependency Injection example


In this article I will show you a simple example for Spring Dependency Injection which is also known as Inversion Of Control (IoC).

I am using Spring Tool Suite for this example even though STS is not mandatory for Spring development.

According to Wikipedia "Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.". I think this is a precise and well defined definition for dependency Injection design pattern.

Now it is our turn to understand how this design patter works and how it help to achieve the goal of design patterns i.e Well defined solutions to commonly existing problems or scenarios.

Lets start with an example, We have a Vehicle interface and 2 child classes Car and Truck. Both Car and Truck has 2 methods printModel() and testEngine() inherited.


I have created a File-> New -> Spring Project named SpringDI.I have created 2 packages in addition to default and created classes and interfaces as below.
Goto Properties->Java Build Path -> Libraries and add Spring related jars as shown below.


Now coding.

 //Vehicle.java 
  
 package vehicles;
  
 public interface Vehicle {  
   public void printModel();  
   public void TestEngine();
   }  
//Car.Java
  
 package vehicles;
  
 public class Car implements Vehicle{  
      public void printModel()  
      {
             System.out .println("I am a car");
      }
  
      public void TestEngine()  
      {
             System.out .println("Testing Car Engine...");
      }
   }  
//Truck.java
  
 package vehicles;
  
 import org.springframework.stereotype.Service;
  
 public class Truck implements Vehicle{
  
  public void printModel()  
  {
     System.out .println("I am a Truck");
  }
  
  public void TestEngine()  
  {
     System.out .println("Testing Truck Engine...");
  }
  }
  
//MySpringBeanWithDependency.java
  
 package testbean;
  
 import vehicles.Vehicle;
  
 public class MySpringBeanWithDependency {  
  private Vehicle vehicle;  
  MySpringBeanWithDependency() {    
   }
  
  MySpringBeanWithDependency(Vehicle veh) {  
    this.vehicle = veh;  
   }
  
  public void run() {    
   vehicle.printModel();  
   vehicle.TestEngine();  
  }  
 }   
//SpringDI.java  
 import org.springframework.beans.factory.BeanFactory;  
 import org.springframework.context.ApplicationContext;  
 import org.springframework.context.support.ClassPathXmlApplicationContext;  
 import testbean.MySpringBeanWithDependency;
  
 public class SpringDI {  
  public static void main(String[] args) {  
   ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/beans.xml");  
   BeanFactory factory = context;  
   MySpringBeanWithDependency test = (MySpringBeanWithDependency) factory  
     .getBean("mySpringBeanWithDependency");  
   test.run();  
  }  
 }   
Now create a beans.xml file in project path with contents as below.



<beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xmlns:aop="http://www.springframework.org/schema/aop"  
  xmlns:context="http://www.springframework.org/schema/context"  
  xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
       http://www.springframework.org/schema/aop  
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  
 <!-- Dependency Injection with annotations -->
  
  <context:component-scan base-package="testbean" />  
  <context:component-scan base-package="vehicles" />
  
 <bean id="mySpringBeanWithDependency" class="testbean.MySpringBeanWithDependency">  
           <constructor-arg>  
                <bean class="vehicles.Car" />  
           </constructor-arg>  
      </bean>  
 </beans> 
 

Now lets see what this really means. We are defining a new bean mySpringBeanWithDependency and asking Spring to create a Car object and inject to constructor of mySpringBeanWithDependency  so that its dependency is resolved.

The output is mentioned below:


The flow is mentioned in the below diagram.

Now we will see how Dependency Injection allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time as mentioned in the definition.
Lets think that we have had a run for Car object and now we need to have a run for Truck object. Is it possible to do that without changing code? Yes. This is achieved because of dependency injection. All what we need to do is to modify beans.xml as below.

 
<bean id="mySpringBeanWithDependency" class="testbean.MySpringBeanWithDependency">  
           <constructor-arg>  
                <bean class="vehicles.Truck" />  
           </constructor-arg>  
      </bean>  
This tells Spring container that  mySpringBeanWithDependency has a dependency which is Truck object and Spring container will inject a Truck object to mySpringBeanWithDependency's constructor.

The output is shown below:


Further more suppose if you dont have the Car class and Truck class available during your testing then you can create a Mock class and test by just changing
<bean class="vehicles.Mock" />
which will greatly help in Test Driven Development.

More tutorials on Spring are on the way. Stay tuned.


Comments

Popular posts from this blog

How to format and install macOS in your old Macbook/ iMac

 You can follow these steps to install a mac OS on an old Mac book following these steps. Here I assume that you have the actual bootable CD for the OS for installation. 1. Restart the laptop 2. Press Command + R key until it shows recovery mode 3. Open Disk Utilities 4. Select the hard drive and try to partition the drive. For example I have created a partition called Partition1 5. Insert bootable CD and restart the laptop. When option comes choose to boot from the CD. 6. Choose partition1 as the place to install the OS 7. Continue the installation process. 8. Once installation is completed then it might need to restart for further updates. 9. Most of the times a more recent compatible version of the OS might be available. In order to upgrade to the more latest compatible OS follow below steps. 11. Find the latest compatible version of OS. 12. Go to apple support sites and manually download the image and click to install. 13. Follow installation instructions and this would upgrade you

How to create a minikube single node cluster for learning Kubernetes

In this post I will explain how to setup a minikube single node kubernetes cluster using AWS EC2 instance which would help anyone who is trying to learn kubernetes and also help them to gain practical knowledge in kubernetes by running kubernetes commands, creating kubernetes objects etc. Minikube is a single node kubernetes cluster which means a kubernetes cluster with only one node that is a single VM. Minikube is only used for learning purposes and it is not an alternative for a real kubernetes cluster and should not be used for development and production usage. In this example I have launched an AWS EC2 instance with below configuration where I will install minikube and related tools. AWS EC2 Instance Configuration AMI: Ubuntu Free tier eligible 64 bit Instance type : t2-large ( For me t2-small or t2-micro is giving performance issues due to less memory) Once the EC2 instance is up and running, login to the instance using below command on terminal. If you are using wi

log4j - How to write log to multiple log files using log4j.properties

In Java applications some times you may need to write your log messages to specific log files with its own specific log properties. If you are using log4j internally then first step that you need to do is to have a proper log4j.properties file. Below example shows 2 log4j appenders which write to 2 different log files, one is a debug log and another one is a reports log. Debug log file can have all log messages and reports log can have log messages specific to reporting on say splunk monitoring. # Root logger option log4j.rootLogger=ALL,STDOUT,debugLog log4j.logger.reportsLogger=INFO,reportsLog log4j.additivity.reportsLogger=false     log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%L - %m%n     # Direct log messages to a log file log4j.appender.debugLog=org.apache.log4j.RollingFileAppender log4j.appender.debugLo