Spring loosely coupled example

The concept of object-oriented is a good design to break your system into a group of reusable objects. However, when system grows larger, especially in Java project, the huge object dependencies will always tightly coupled causing objects very hard to manage or modify. In this scenario, you can use Spring framework to act as a central module to manage all the object dependencies easily and efficiently.

Output Generator Example

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

File : IOutputGenerator.java – An interface for output generator

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

File : 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");
	}
}

File : 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");
	}
}

There are couple of ways to call the IOutputGenerator, and how to use Spring to avoid objects to coupled tightly with each other.

1. Method 1 – Call it directly

Normal way, call 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
In this way, the problem is the “output” is coupled tightly to CsvOutputGenerator, every change of output generator may involve code change. If this code is scattered all over of your project, every change of the output generator will make you suffer seriously.

Method 2 – Call it with helper class

You may think of creating a helper class to move all the output 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 looks 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 still involves minor code change.

Method 3 – Spring

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

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 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. When output changed, you need to modify the Spring XML file only, no code changed, means less error.

Conclusion

With Spring framework – Dependency Injection (DI) is a useful feature for object dependencies management, it is just elegant, highly flexible and facilitates maintainability, especially in large Java project.

Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: water ionizer()

  • Pingback: paypal loans()

  • Pingback: water ionizer machine()

  • Pingback: car parking()

  • Pingback: xnxx()

  • Pingback: parking()

  • Pingback: great prices on DIRECTV()

  • Pingback: Sat TV()

  • Pingback: Blue Coaster33()

  • jeff

    Great Example! Thanks Mr.Mkyong for clear explanation and showing the differences between three approaches. Great work! Keep it up.

  • Bogdan

    Or simplier, without Helper and no coupling :

    ApplicationContext context =
    new ClassPathXmlApplicationContext(new String[] {“SpringBeans.xml”});

    IOutputGenerator output = (IOutputGenerator)context.getBean(“JsonOutputGenerator”);
    output.generateOutput();

    • BelianskyAS

      And you have to change source code, when you need to use the CsvOutputGenerator. This is tight coupling.

      p.s. Sorry my bad english :)

      • Steve J

        I am not sure why people say changing the spring config is not a code change. The bad part about changing the spring config file is that it is not under unit test so there is no easy to tell if you have broken anything…

        • Alex

          Assuming you define (needs to be the same, because product owner said so) and call the output.generateOutput in more than one class, if you need to change to Csv you will have to modify 2 or more classes, instead of 1 xml file. Low Coupling is also defined by extensibility, not only by what your source code looks like at the moment.

        • http://www.readingcraze.com Umer

          Steve,

          I have used my actual spring configuration file under my unit test case, all of my test code use actual spring configuration file, so If we have make incorrect changes in spring configuration , my test case start getting failed, but I also agree spring configration change is a ” CHANGE “.

  • http://www.simplecodestuffs.com mohiadeen

    Nice explanation . thanks :)

  • manisg

    hjkhjk

  • Ayaz

    Its good tutorial but my question is it looks same just the difference is you placed bean.xml what if i want that both can be accessed by xml like csv and xml both. sory if my question is wrong because iam new in spring. but regular reader of your articles. Thanks

  • Abdul Gafoor

    Excelent clarification…

  • http://No Selvakumar

    cool Example

  • http://mkyong.com Rajpal Singh

    Hello sir,

    You said that when output changed, you need to modify the Spring XML file only.

    Can you explain with example what type of code we change in the output.

    Help me…..

    • Chandra Sekhar

      As per the below configuration,

      we are attaching a CsvOutputGenerator to the OutputHelper. If we want to attach JsonOutputGenerator, then we change the spring configuration as below:

      Hope this clarifies ?

  • Suri

    I don’t get it. Instead of one helper class for each implementation, we are ending up with one spring config for each implementation. Is the advantage here the ability to execute implementation of choosing without re-compiling ?

    • Suri

      Sorry ! spoke too soon. Very first comment and subsequent reply by Mr.Yong, made me believe I should be thinking differently. I am very glad I found this site Mr.Yong, Thank you.

  • http://[email protected] Srikanth

    Really useful….keep posting like these…

  • Rajesh Kumar

    Nice, precise and clear information. Thanks.

  • Trivi

    Hi mkyong,

    Great help to the java community, best regards.

  • Suyog

    can anyone tell me what is the difference between ApplicationContext and BeanFactory

     ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{&quot;context.xml&quot;});
     BeanFactory context = new ClassPathXmlApplicationContext(context.xml);
  • Suyog

    // this is for CsvOutputGenerator but what to do if i want both CsvOutputGenerator and sonOutputGenerator
    //can i write like this

    • TestConfig

      call like this

      OutputHelper output = (OutputHelper)context.getBean(“OutputHelper”);
      output.generateOutput();

      OutputHelper output1 = (OutputHelper)context.getBean(“OutputHelper1″);
      output1.generateOutput();

      • pizero

        :)))
        output, output1, outputhelper, outputhelper1 ….. :)))

        so all of you think that naming variables like a1, a2, a3 and so on
        is elegant and readable?

        very interesting ….

  • Muhammad Amjad

    Excellent Document, Or i can say excellent website, Each step is explained in detail and we can easily understand the stuff

    Welldone Mr. Mkyong

    • http://www.mkyong.com mkyong

      Thanks for your kind words.

    • Shawn C

      totally agree ! excellent work !

  • sreenivas

    neat and clean explaination…. thanks a lot boss !!!!!!!!!

  • sreenivas

    Very good explaination….. Thanks alot…

  • Azhar

    Cool example,

  • atul

    really great job.

    Thank you !
    Atul

  • suresh

    Thanks for good Explanation…

  • java_sridhar

    good explanation.

  • Siddhraj Atodaria
     Thanks Bro
  • Siddhraj Atodaria

    Thanks Bro,

  • http://emrpms.blogspot.in/ Senthil

    Good Article. But still i am new to java world, so still i am not convinced why need this spring service layer. In the above examples, you have mentioned that

    “every change of output generator may involve code change. If this code is scatter over all of your project, every change of the output generator will make you suffer seriously. ”

    But if you could improve your example with change happen with service layer and without service layer, then it would be great

  • Beniton

    Excellent

  • Bonus

    Thank you very much. Great Example of loosely coupling.
    First time I got it right.
    Great tutorial.

    Regards!!!

  • Pingback: what is the difference between loosly coupling and tightly coupling?()

  • Shyam

    Hi Mkyong,

    Thanks for explaining spring programaticaly which one I was looking for long time.

    I think you have missed one return time in the Helper class.Could you please look into that.Here is the code.

     public OutputHelper(){
    		outputGenerator = new CsvOutputGenerator();
    	}

    Thanks,
    Shyam

    • http://www.mkyong.com mkyong

      Sorry, i don’t get you?

    • Tim
      public OutputHelper(){
          outputGenerator = new CsvOutputGenerator();
      }

      This is a Constructor, which does not return.

  • Arvind

    Hi Mkyong,

    Great posts! I found explainations are to the point, no verbose. great resource for young developers.

    I appreciate your selfless effort

    • http://www.mkyong.com mkyong

      sharing is one of the great way to improve :)

      • sam

        Can you provide material about web services…thank you.

      • alioune

        greatfull tutorial.
        I’m very happy to meet this one.
        thank’s you very mutch

  • Raghu

    Hi Mkyong,

    Nice tutorial, Thanks.

  • Halbert

    Hi..

    This is why I haven’t touched Spring from the beginning it came out but now I got no choice since a project is required me to use it.

    If we compare method 2 and method 3 above, actually the work load is the same. Both still have to do modification. Method 3 doesn’t need to change the code, but still need to change the XML. It’s more or less shifting the work to XML. And worse, the tightly coupled problem that we want to get rid of is now at the XML. So what’s the advantage? As the matter of fact, now we have added one more layer (Spring) which means more works, more memory, more CPU power, and more possible bugs introduced. And then when the project grows big, the XML file would be hard to be managed.

    Just my 2 cents… care to share your view?

    p.s. Btw, thanks for the tutorials. Still going thru them as of this msg is being posted.

    • http://www.mkyong.com mkyong

      Dependency injection (DI) is a design pattern, that’s used to solve the common tightly components coupled issue, just Spring makes DI very easy to implement.

      In a large project or multiple developers involved, the best practice is always providing the interface to the client, so that any changes in the implementation class will not require to change at the client side.

      In method 2, if you want to change the outputGenerator, you have to modify the helper class, and any code changed may cause some new potential bugs as well (especially for junior developer). The best practice is always minimal the code change as little as possible, avoid is better. Furthermore, when the helper class grows bigger, not every developer has enough confidence to make a simple change and commit the code :)

      In method 3, if you want to change the outputGenerator, you can just create a new implementation class and inject into your interface via XML, no code is modified, and you can roll back your code easily. The workload may be similar, but the flexibility and maintainability should take it into consideration. For anti-XML person, you can use Spring annotations to auto wire the implementation class.

      “added one more layer (Spring) which means more works, more memory, more CPU power, and more possible bugs introduced”
      More work at initial development, but less work in future. More memory or CPU power, may be, but for years of Spring development, i just do not feel there are any serious performance impact. More bugs? Definitely no, Spring is a mature and successful framework, there shouldn’t any critical bug itself, it’s more on how developer using it.

      “And then when the project grows big, the XML file would be hard to be managed.”
      When the project grow big, you may more harder to find your helper class :). In addition, when project grow big, so does helper class, often times, you just do not wish to change a single line of a “big” class. Let say, your senior is left company, you have to take over his job, will you rather make change in a unknown “big” class or make a single change in XML file? Just an example.

      During initial development, you may feel why you need Spring? Why added one more layer? The benefits will be obvious when the user requirement has kept changing (It’s always, never end! No matter you are using agile development or waterfall, sad…but true) or doing maintenance in future.

      Hope my scenarios are not misleading or confuse you :), try consulting the Spring’s book titled “Spring Recipe” for more Spring explanation. Hope helps.

      • anil

        Good Discussion on Spring IOC . Clears my doubts .

      • Siddhraj Atodaria

        good

      • lakshmi

        Excellent explanation.

        Thanks

      • Dinesh Ram

        Hi Sir,
        Thanks for your good explanation. But I am not clear ““every change of output generator may involve code change. If this code is scatter over all of your project, every change of the output generator will make you suffer seriously.”

        Method1:
        In “CsvOutputGenerator” class if i am changing the method name as well as need to change the calling method of name in “App” class.

        Method 3:
        But If i use spring no need to modify the method name(generateOutput()) in implementation class whether modification required concentrate on XML file. Even though I am calling same “CsvOutputGenerator” class from “App” class. How?
        So,Why no need of modification in App class?

        Please anyone clear my doubts.

      • sravan

        gud explanation sir

      • Atul

        I m exactly with Halbert on this one. With the rush to adopt the buzzword of ‘dependency injection’, few have actually quantified the ROI on refactoring or even architecting a new application with DI front and center.
        I do understand the need for loose coupling, when applied in context of OO programming, which is to achieve maximum reusability of the code(objects).
        As far as DI goes, from my personal experience, the advantages of changing a helper vs changing an XML doc are overblown. First off, I like changing helper as any typo would be caught immediately at compile time by any mordern IDE, while detecting any such error in XML has to defer till runtime. Secondly, you can break your helper into separate logical classes to avoid it being a humungous unmanageable class.
        I believe DI would be using Reflections under covers to instantiate objects to inject, reflections in one of the costliest functionality in Java with performace overhead.
        Only advantage I can think of is that if you somehow take the XML config file out of the EAR/WAR, then you don’t need to break jar/recompile app, but can change the application on the fly based on the requirement, but usually Spring XML config is packaged within the app.
        That being said I feel I am wrong but still need some convincing..

    • http://www.readingcraze.com Umer

      I think there is one big part you are missing, the managing application become easier, we have one project which we have been working 3/4 years, we have 3/4 xml configuration all classes, their properties is in one xml file. Its very easy to manage them.

  • Pingback: Spring Tutorials | J2EE Web Development Tutorials()

  • Pingback: Falling in Love: A Natural Progression | InPurplish()