The object-oriented is a good design to break your system into a group of reusable objects. However, when a system grow large, especially in Java project, the huge object dependencies will tightly coupled and causing the objects more hard to manage or modify. In this scenarios, you need Spring framework to act as a central module to manage all the object dependencies easily.

Output Generator Example

Let see an example, assume your project has a function to output the content as Csv or Json format. Your code may look like following:

IOutputGenerator.java

An interface for output generator

package com.mkyong.output;
 
public interface IOutputGenerator
{
	public void generateOutput();
}

CsvOutputGenerator.java

A Csv output generator to implement the IOutputGenerator interface.

package com.mkyong.output.impl;
 
import com.mkyong.output.IOutputGenerator;
 
public class CsvOutputGenerator implements IOutputGenerator
{
	public void generateOutput(){
		System.out.println("Csv Output Generator");
	}
}

JsonOutputGenerator.java

A Json output generator to implement the IOutputGenerator interface.

package com.mkyong.output.impl;
 
import com.mkyong.output.IOutputGenerator;
 
public class JsonOutputGenerator implements IOutputGenerator
{
	public void generateOutput(){
		System.out.println("Json Output Generator");
	}
}

How you call your output generator to avoid objects tightly coupled in your project?

Method 1 – Call it directly

You can it directly

package com.mkyong.common;
 
import com.mkyong.output.IOutputGenerator;
import com.mkyong.output.impl.CsvOutputGenerator;
 
public class App 
{
    public static void main( String[] args )
    {
    	IOutputGenerator output = new CsvOutputGenerator();
    	output.generateOutput();
    }
}
Problem

If this code snippet is scatter over all your project, every change of output generator will make you suffer a painful tedious work. The problem is your output is tightly coupled to CsvOutputGenerator, every change of output generator may involve code change.

Method 2 – Call it with helper class

You may think of create a helper class to move all the implementation inside.

package com.mkyong.output;
 
import com.mkyong.output.IOutputGenerator;
import com.mkyong.output.impl.CsvOutputGenerator;
 
public class OutputHelper
{
	IOutputGenerator outputGenerator;
 
	public OutputHelper(){
		outputGenerator = new CsvOutputGenerator();
	}
 
	public void generateOutput(){
		outputGenerator.generateOutput();
	}
 
}

Call it via helper class.

package com.mkyong.common;
 
import com.mkyong.output.OutputHelper;
 
public class App 
{
    public static void main( String[] args )
    {
    	OutputHelper output = new OutputHelper();
    	output.generateOutput(); 
    }
}
Problem

This look more elegant, and you only need to manage a single helper class, however the helper class is still tightly coupled to CsvOutputGenerator, every change of output generator is still involve minor code change.

Method 3 – Spring

In this scenario, Spring Dependency Injection (DI) is a good choice. The Spring can make your output generator loosely coupled to any output generator.

Spring Example

Minor change in OutputHelper class.

package com.mkyong.output;
 
import com.mkyong.output.IOutputGenerator;
 
public class OutputHelper
{
	IOutputGenerator outputGenerator;
 
	public void generateOutput(){
		outputGenerator.generateOutput();
	}
 
	public void setOutputGenerator(IOutputGenerator outputGenerator){
		this.outputGenerator = outputGenerator;
	}
}

Create a Spring bean configuration file and declare all the your Java object dependencies here.

<!-- Spring-Common.xml -->
<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.mkyong.output.OutputHelper">
	<property name="outputGenerator" ref="CsvOutputGenerator" />
</bean>
 
<bean id="CsvOutputGenerator" class="com.mkyong.output.impl.CsvOutputGenerator" />
<bean id="JsonOutputGenerator" class="com.mkyong.output.impl.JsonOutputGenerator" />
 
</beans>

Call it via Spring

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.mkyong.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.generateOutput();
 
    }
}

Now, you just need to change the Spring XML file for a different output generator.

Conclusion

This Spring framework – Dependency Injection (DI) is a useful feature for the object dependencies management, it is just elegant, highly flexible and easy for maintainability.

This article was posted in Spring category.