Thursday, August 6, 2015

Spring Dependency Injection / Inversion of Control (IoC)

INTRODUCTION

  • Spring Framework's very basic concept is Dependency Injection or IoC.
  • It is a reverse process of traditional java object initialization and instantiation.
  • When a java program starts running it, it will first create all the dependent object and then start executing even though those objects are used or not.
  • But Spring Framework's Dependency Injection will reverse the process of creating the object for any Class.
  • It will create the object whenever it is required at run-time.

SOFTWARES & TOOLS

  1. Eclipse IDE (Mars2) with Spring Plugins Installed.
  2. Java 1.6

USECASE

I would like to explain with a simple program which will read the data from different sources (flat file, db or from other sources)

IMPLEMENTATION

STEP 1

Create an interface for file reading.
package com.jbr.springcore.ioc;

public interface DataReader {
 String readData();
 String getSource();
}

STEP 2

Create an implementation for flat file reading.
package com.jbr.springcore.ioc;

import java.io.File;
import java.io.FileNotFoundException;

import java.util.Scanner;

public class FlatFileDataReader implements DataReader {
 private StringBuilder builder;
 private Scanner scanner;

 public FlatFileDataReader(String fileName) throws FileNotFoundException {
   scanner = new Scanner(new File(fileName));
   builder = new StringBuilder();
 }

 @Override
 public String readData() {
   while (scanner.hasNext()) {
     builder.append(scanner.next() + " ");
   }

   return builder.toString();
 }

 private String source;

 public void setSource(String source) {
   this.source = source;
 }

 public String getSource() {
   return source;
 }
}

STEP 3

Create service class.
package com.jbr.springcore.ioc;

public class DataReaderService {

 private DataReader dataReader;

 public DataReaderService(DataReader dataReader) {
   this.dataReader = dataReader;
 }

 public String readData() {
   return dataReader.readData();
 }

 public String getSource() {
   return dataReader.getSource();
 }
}

Now your bean is ready, configure it in bean configuration file.

STEP 4

Create Bean Configuration file & Properties file

  • This file will contain one or more bean configurations which will be used in your application
  • Changing the hardcoded values in the bean configuration file is a hectic job. So that I have created a property file with a list of properties and configured in bean 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:application.properties"></property>
</bean>

<bean id="dataReaderService" class="com.jbr.springcore.ioc.DataReaderService">
<constructor-arg ref="flatFileReader" />
</bean>

<bean id="flatFileReader" class="com.jbr.springcore.ioc.FlatFileDataReader">
<constructor-arg value="${fileName}" />
<property name="source" value="${dataSource}"></property>
</bean>

</beans>

STEP 5

Create a properties file to have necessary property.
fileName=data.txt
dataSource=Data From Flat File

STEP 6

Create a client program to read the data from the file.
package com.jbr.springcore.ioc;

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

public class DataReaderMain {

 ApplicationContext applicationContext;
 DataReaderService dataReaderService;

 public DataReaderMain() {
   applicationContext = new ClassPathXmlApplicationContext("ioc-beans.xml");
   dataReaderService = (DataReaderService) applicationContext.getBean("dataReaderService");
 }

 public String getData() {
   return dataReaderService.readData();
 }

 public String getSource() {
   return dataReaderService.getSource();
 }

 public static void main(String[] args) throws Exception {
   DataReaderMain dataReaderMain = new DataReaderMain();
   System.out.println("Data Source: " + dataReaderMain.getSource());
   System.out.println("Data: " + dataReaderMain.getData());
 }
}

INPUT

Create a file and have some data like below.
This is a sample spring program

OUTPUT


Data Source: Data From Flat File
Data: This is a sample spring program

Further, if you want to read data from a database, write a separate class which will implement the DataReader Interface and configures it in the bean configuration.
Hope this post helps to understand the auto-wiring without annotation. I will cover the auto-wiring with annotation in another post.
Please share your comments and suggestions.
Happy Knowledge Sharing!!!

No comments :

Post a Comment