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.

Or simplier, without Helper and no coupling :
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {“SpringBeans.xml”});
IOutputGenerator output = (IOutputGenerator)context.getBean(“JsonOutputGenerator”);
output.generateOutput();
And you have to change source code, when you need to use the CsvOutputGenerator. This is tight coupling.
p.s. Sorry my bad english :)
Nice explanation . thanks :)
hjkhjk
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
Excelent clarification…
cool Example
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…..
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 ?
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 ?
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.
Really useful….keep posting like these…
Nice, precise and clear information. Thanks.
Hi mkyong,
Great help to the java community, best regards.
can anyone tell me what is the difference between ApplicationContext and BeanFactory
// this is for CsvOutputGenerator but what to do if i want both CsvOutputGenerator and sonOutputGenerator
//can i write like this
call like this
OutputHelper output = (OutputHelper)context.getBean(“OutputHelper”);
output.generateOutput();
OutputHelper output1 = (OutputHelper)context.getBean(“OutputHelper1″);
output1.generateOutput();
:)))
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 ….
Excellent Document, Or i can say excellent website, Each step is explained in detail and we can easily understand the stuff
Welldone Mr. Mkyong
Thanks for your kind words.
totally agree ! excellent work !
neat and clean explaination…. thanks a lot boss !!!!!!!!!
Very good explaination….. Thanks alot…
Cool example,
really great job.
Thank you !
Atul
Thanks for good Explanation…
good explanation.
Thanks Bro,
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
Excellent
Thank you very much. Great Example of loosely coupling.
First time I got it right.
Great tutorial.
Regards!!!
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.
Thanks,
Shyam
Sorry, i don’t get you?
This is a Constructor, which does not return.
Hi Mkyong,
Great posts! I found explainations are to the point, no verbose. great resource for young developers.
I appreciate your selfless effort
sharing is one of the great way to improve :)
Can you provide material about web services…thank you.
greatfull tutorial.
I’m very happy to meet this one.
thank’s you very mutch
Hi Mkyong,
Nice tutorial, Thanks.
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.
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.
Good Discussion on Spring IOC . Clears my doubts .
good
Excellent explanation.
Thanks
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.
gud explanation sir
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..