Spring Tutorial - Spring Loosely Coupled








In the following we will see how Spring would help us to achieve loosely coupled code.

Project Code

We would create a project which has several classes. Th project would output data in different format. We can choose to output the data in CSV format or JSON format.

First we will create a Java interface for print.

package com.java2s.output;
public interface Printer
{
  public void print();
}

After that we would create CSV printer which will output data in CSV format. The CSV printer implements the Printer interface.

package com.java2s.output.impl;
import com.java2s.output.Printer;
public class CSVPrinter implements Printer
{
  public void print(){
    System.out.println("Csv Output Printer");
  }
}

Then it is time to create JSON printer which will output message in JSON format. The JSON printer also implements the Printer interface.

package com.java2s.output.impl;
import com.java2s.output.Printer;
public class JSONPrinter implements Printer
{
  public void print(){
    System.out.println("Json Output Printer");
  }
}




Couple Code

We have several ways to use the CSVPrinter or JSONPrinter. First we can call it directly.

package com.java2s.common;
import com.java2s.output.Printer;
import com.java2s.output.impl.CSVPrinter;
public class App 
{
    public static void main( String[] args )
    {
      Printer output = new CSVPrinter();
      output.print();
    }
}

It is easy to create CSVPrinter in this way. But we will have to change the source code if we want to switch to JSONPrinter we will have to change the source code and recompile.

For the code above it is easy to change since it has two lines of code. Suppose we have thousands of thousands of code and the CSVPrinter had been declared hundreds of time.





Spring Way

By using Spring Dependency Injection (DI) we can declare Java Beans in the Spring configuration xml file. Then wire the Java Beans in the xml file. In this way Spring can make our printer loosely coupled to the different Printer implementations.

We change the Helper class to accept the Printer.

package com.java2s.output;
import com.java2s.output.Printer;
public class OutputHelper
{
  Printer outputGenerator;
  public void print(){
    outputGenerator.print();
  }
  public void setOutputGenerator(Printer outputGenerator){
    this.outputGenerator = outputGenerator;
  }
}

Then we have to create a Spring bean configuration file and declare all your Java object dependencies here.

<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-2.5.xsd">
  <bean id="OutputHelper" class="com.java2s.output.OutputHelper">
    <property name="outputGenerator" ref="csvPrinter" />
  </bean>
  <bean id="csvPrinter" class="com.java2s.output.impl.CSVPrinter" />
  <bean id="jsonPrinter" class="com.java2s.output.impl.JSONPrinter" />
</beans>

Call it via Spring

package com.java2s.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.java2s.output.OutputHelper;
public class App 
{
    public static void main( String[] args )
    {
      ApplicationContext context = 
         new ClassPathXmlApplicationContext(new String[] {"Spring-Common.xml"});
      OutputHelper output = (OutputHelper)context.getBean("OutputHelper");
      output.print();
    }
}

To switch Printer, we just need to change the Spring XML file for a different Printer. When Printer changed, we need to modify the Spring XML file only.