Free Data Structures and Algorithms Course









Subscribe below and get all best seller courses for free !!!










OR



Subscribe to all free courses

How to create a loosely coupled Java application using Spring Frameworks Dependency Injection ?.

A simple Java code demonstrating how to create a loosely coupled Java application using Spring Frameworks Dependency Injection

Problem : A Tightly Coupled Java Application -

1. An Interface ShapeCreator.java which exposes a method named as createShape() to draw a specific type of shape.

package com.hubberspot.spring.tight.coupling;

// An Interface which exposes createShape method
// to application to draw a shape of specific
// type
public interface ShapeCreator {

 public void createShape();

}




2. Let us create two classes by name Triangle.java and Circle.java which implements above created ShapeCreator interface. These classes will provide the concrete implementation to createShape() to provide creation of specific shape.

Triangle.java

package com.hubberspot.spring.tight.coupling;

// An Interface which exposes createShape method
// to application to draw a shape of specific
// type
public interface ShapeCreator {

 public void createShape();

}



Circle.java

package com.hubberspot.spring.tight.coupling;


public class Circle implements ShapeCreator {

 @Override
 public void createShape() {

  System.out.println("Circle Shape Drawn ...");

 }

}




3. Let us consider a class by name ShapeCreatorService.java . This class creates a particular shape by calling draw() method and has an reference of Triangle object hold by a type ShapeCreator which is implemented by Triangle class.

package com.hubberspot.spring.tight.coupling;

public class ShapeCreatorService {

 private ShapeCreator shapeCreator = new Triangle();

 public void draw() {
  shapeCreator.createShape();
 }

}




4. Let us consider a class ShapeCreatorApplication.java which by name indicates that it is a class which will run and create a shape for us. It has a main method which creates a instance of ShapeCreatorService and calls draw() to create a shape for us.

package com.hubberspot.spring.tight.coupling;

public class ShapeCreatorApplication {

 public static void main(String[] args) {

  ShapeCreatorService service = new ShapeCreatorService();
  service.draw();

 }

}



Output of the program : 

















Where is the problem for Tight-Coupling ?.

The problem lies within the class ShapeCreatorService.java. This class has a ShapeCreator variable which points to Triangle object. Here new operator is the main culprit for having tight coupling of Triangle to ShapeCreatorService class. What if in future we need to draw Circle. This code above will work fine for creating Triangle class, but having new operator in a class creates a tight coupling for the class in which new operator is used with the class whose object it creates. If in future we need to remove Triangle and add Circle object we need to modify the source code for the class. In order to remove this tight coupling between the class we use Spring Frameworks Dependency Injection technique demonstrated below



So what should we change , instead of ShapeCreatorService class creating the instance of a class Triangle or Circle, why not it assign that task to Spring Container which creates a instance of a bean by reading a Spring Configuration file and return that instance to demanding class by Dependency Injection. Lets see...

1. We create a Spring Configuration file which has following beans -




1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" 
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
    <bean id="triangle" class="com.hubberspot.spring.loose.coupling.Triangle"></bean>
    <bean id="circle" class="com.hubberspot.spring.loose.coupling.Circle"></bean>
    <bean id="createShape"
        class="com.hubberspot.spring.loose.coupling.ShapeCreatorService">
        <property name="shapeCreator" ref="triangle"></property>
    </bean>
</beans>


Each class or we can say each bean is defined using the bean tag in the configuration file above. The id attribute in the spring.xml file provides a name which is unique in the xml file and class attribute provides the actual class for this id. The bean tag has a tag called as property tag which is used to set property of a particular bean. Here property tag has a ref attribute which helps injecting the instance to a bean. Here ref tag points to id of bean whose instance we have to inject. Here ref tag uses setter method of a bean to inject a instance. Let say we modifiy our ShapeCreatorService class which instead of having a new operator uses a setter method for injection of an object to it.

Modified ShapeCreatorService class for Loose Coupling -


package com.hubberspot.spring.loose.coupling;

public class ShapeCreatorService {

 private ShapeCreator shapeCreator;

 public ShapeCreator getShapeCreator() {
  return shapeCreator;
 }

 public void setShapeCreator(ShapeCreator shapeCreator) {
  this.shapeCreator = shapeCreator;
 }

 public void draw() {
  shapeCreator.createShape();
 }

}




Modified Application class for implementing calling of ShapeCreator instance by reading Spring Configuration file


package com.hubberspot.spring.loose.coupling;

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

public class ShapeCreatorApplication {

 public static void main(String[] args) {

  // Instead of below solution we use Spring's Dependency 
  // Injection 

  /*ShapeCreatorService service = new ShapeCreatorService();
  service.draw();*/

  // ApplicationContext is a Spring interface which 
  // provides with the configuration for an application. 
  // It provides us with all the methods that BeanFactory 
  // provides. It loads the file resources in a older 
  // and generic manner. It helps us to publish events to the
  // listener registered to it. It also provides quick support
  // for internationalization. It provides us with the object 
  // requested, it reads the configuration file and provides
  // us with the necessary object required.
  // We are using concrete implementation of ApplicationContext
  // here called as ClassPathXmlApplicationContext because this 
  // bean factory reads the xml file placed in the classpath of 
  // our application. We provide ClassPathXmlApplicationContext
  // with a configuration file called as spring.xml placed
  // at classpath of our application. 
  ApplicationContext context = 
    new ClassPathXmlApplicationContext(("spring.xml"));

  // In order to get a object instantiated for a particular bean 
  // we call getBean() method of ClassPathXmlApplicationContext
  // passing it the id for which the object is to be needed. 
  // Here getBean() returns an Object. We need to cast it back 
  // to the ShapeCreator object. Without implementing new keyword we 
  // have injected object of ShapeCreator just by reading an xml 
  // configuration file.
  ShapeCreatorService service = 
    (ShapeCreatorService)context.getBean("createShape");

  // Calling our functionality
  service.draw();

 }

}




So next time if we want to get Circle shape drawn we just replace ref tag value to point to circle instead of triangle. So by doing such tasks we have now implemented a application which is loosely coupled and if any changes comes in near future we can change the configuration file as per our design.
 
© 2021 Learn Java by Examples Template by Hubberspot