Spring Dependency Injection - An Introductory Tutorial
The concept of DI transcends Spring. Thus, you can accomplish DI without Spring as follows:
DI without Spring
package com.arcmind.springquickstart;
import java.math.BigDecimal;
public class AtmMain {
public void main (String[] args) {
AutomatedTellerMachine atm = new AutomatedTellerMachineImpl();
ATMTransport transport = new SoapAtmTransport();
/* Inject the transport. */
((AutomatedTellerMachineImpl)atm).setTransport(transport);
atm.withdraw(new BigDecimal("10.00"));
atm.deposit(new BigDecimal("100.00"));
}
}
Then injecting a different transport is a mere matter of calling a different setter method as follows:
Injecting a different dependency
ATMTransport transport = new SimulationAtmTransport();
((AutomatedTellerMachineImpl)atm).setTransport(transport);
To use Spring to inject a dependency you could do the following:
Using Spring to manage dependencies
package com.arcmind.springquickstart;
import java.math.BigDecimal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AtmMain {
public static void main (String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("classpath:./spring/applicationContext.xml");
AutomatedTellerMachine atm = (AutomatedTellerMachine) appContext.getBean("atm");
atm.withdraw(new BigDecimal("10.00"));
atm.deposit(new BigDecimal("100.00"));
}
} /spring/applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?>
<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="atmTransport" class="com.arcmind.springquickstart.SoapAtmTransport" />
<bean id="atm" class="com.arcmind.springquickstart.AutomatedTellerMachineImpl">
<property name="transport" ref="atmTransport" />
</bean>
</beans>
Figure 1 illustrates how Spring injects the dependency using property setter method injection.

The application context is the central interface to the Spring DI container. In the application context, you declare two beans, atmTransport and atm, with a bean tag. Then you use the property tag to inject the atmTransport bean into the transport property. This effectively calls the setter method of the AutomatedTellerMachineImpl transport property (setTransport(...)).
The major capabilities that the application context provides include (taken from API docs):
- Bean factory methods for accessing application components
- The ability to load file resources in a generic fashion
- The ability to resolve messages, supporting internationalization
The focus of this article is bean factory methods and DI.
About the author
Rick Hightower is CTO of Mammatus and is an expert on Java and Cloud Computing. Rick is invovled in Java CDI advocacy and Java EE. CDI Implementations - Resin Candi - Seam Weld - Apache OpenWebBeans
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Cody A_ replied on Tue, 2008/11/11 - 8:40am
Very nice article,
One of my biggest obstacles has been grasping DI conceptionally. I think you did a good job in showing the "tutorial" perspective of DI. Can't wait to see more...
Rick Hightower replied on Thu, 2008/11/13 - 12:09pm
Jakob Jenkov replied on Tue, 2008/11/11 - 2:55pm
Hi Rick,
I just browsed the article quickly. Seems you have spent a long time putting this piece together! Kudos to you!
If I may comment a bit on the title, I think it is perhaps slightly mis-leading. This article, though definately useful, is more of a "Dependency Injection with Spring"-tutorial. Some of the concepts are unique to Spring, and the configuration examples definately are too. But readers new to dependency injection could be lead to believe, that dependency injection is only something you can do with Spring. But there are Pico, Guice and Butterfly Container too, among others.
You do mention Spring early on page 1, so I guess the "mislead" reader is quickly corrected. Anyways, with frameworks growing as huge as Spring is, it is nice with "getting started / introductory" articles like this one.
I too wrote a tutorial on dependency injection, but my tutorial tries to explain the concept a bit more detached from any specific DI container (yet it shows examples using Butterfly DI Container). In the end of this tutorial I also explain when and when NOT to use dependency injection (according to my opinion / experience).
Rick Hightower replied on Tue, 2008/11/11 - 3:05pm
in response to:
Jakob Jenkov
Geoffrey Chandler replied on Tue, 2008/11/11 - 3:05pm
Hovanes Gambaryan replied on Tue, 2008/11/11 - 3:06pm
chris mathias replied on Tue, 2008/11/11 - 3:09pm
Nice article Rick. I love the DI concept, but I struggled with it at first, as I imagine most developers do who have been authoring more traditional workhorse code. I find it amazing how using things like Spring let me get down to business...most of my code these days actually does only what it needs to do rather than taking twenty lines to set up the three important ones.
I think it's great that heavyweights like yourself that really 'get' this stuff take the time to turn back, and teach the rest who are lagging.
I would disagree with Jakob's observation as I feel you did mention alternatives more than once. (though yes, your samples are Spring). Spring has become a monster, but from my experiences so far, is still the sharpest knive in the drawer.
Keep it up Rick - the one I'm personally waiting for is the AspectJ introduction (specifically tapping cut points in compiled libraries). Can you just DI that into my head please?
Tom Cellucci replied on Tue, 2008/11/11 - 3:21pm
excellent concrete example of using dependency injection. I am a long-time Spring user but there were several useful pieces of information on some of the newer features. I will definitely add the 'p:' tags to my toolkit. Thanks,
-tom
Paul Hixson replied on Tue, 2008/11/11 - 3:24pm
Jakob Jenkov replied on Tue, 2008/11/11 - 3:59pm
Walter Bogaardt replied on Tue, 2008/11/11 - 4:38pm
Great explanation. I was wondering what happens to the role of the applicationContext with all the annotations. It was one of those todo things to look at when I had some cycles, and you cleared it up in a few lines.
I'd like to see something on the spring annotations features like @Bean and javaconfig, and spring or DI in the web world of servlets, jsf, jsp. Keep up the good articles.
Steven Baker replied on Wed, 2008/11/12 - 6:41am
great read, but it feels like it missed a key part: actually integrating spring into an app.
i.e. starting it up, adding the context/listener to web.xml or something similar like even using the bean factory.
Stuart Halloway replied on Wed, 2008/11/12 - 9:15am
Hi Rick,
Responding per your request for comments. I found the tutotial easy-to-follow, but I don't want to follow where it goes. :-) I think DI is overrated, and both XML and Annotations are bad ways to do it. If a team is committed to DI, I would recommend a Groovy, JRuby, or Clojure based DSL.
Cheers,
Stuart
John Fryar replied on Wed, 2008/11/12 - 9:53am
You have particular skill with examples. The examples you provide here, as with your JSF tutorial on developerworks, are USEFUL and clearly illustrate some key concepts. The images you use to highlight how the xml is related to the java code and how the annotated classes related one-to-another are top-notch. You could probably expand that approach into a book and it would be very helpful to both newbies and experience Spring developers.
I agree with Jakob that the title is misleading. This really isn't about DI so much as it is about DI using Spring. That being said, it's a fantastic article for anyone looking for an introduction to DI using Spring.
I look forward to the follow-up articles.
Solomon Duskis replied on Wed, 2008/11/12 - 2:06pm
This is a follow up to your linkedIn question:
I'd like to revise this question a bit to: "When should you annotate a class with Injection configuration, and when should you externalize the Injection configuration?"
IMHO, the more generic question is key on how you should think about DI. 80-90% of the time you can annotate a class with DI info. The types of annotations you're adding are "I need an instance of X class injected here" (for example Spring's @Autowired and @Required, JEE's @Resource and Guice's @Inject), "I am available for use" (Spring's @Component/@Service/@Controller/@Repository, JEE's @Stateless/..., and Guice's @ImplementedBy/@Singleton/...), and "I need/am a specific instance of X class/interface" (Spring's @Qualifier, and Guice's @BindingAnnotation).
There are quite a few reasons for the other 10-20% of cases that don't make sense, and for those, DI configuration needs to be put somewhere else, for example in Spring XML, Spring JavaConfig or Guice Modules/Producers. Some of the reasons are:
1) The class is defined in a location that you don't have control over, such as a vendor jar.
2) The class encapsulates an environmental configuration, such as setting up a DataSource or Hibernate configuration
3) You need more than one instance of the same exact class
Some cases have a 100% need to be externalized (for example, database and hibernate). However, there are plenty of cases that are pretty tricky to either categorize or implement.
One quick example of a borderline common case is a Spring @Controller. I often configure MVC Controllers with a JSP file or Tile that I'd like to use. You can do that by injecting a String value (with a Qualifier "mySuccssView") into the controller; however, Spring doesn't let you use the @Autowired annotation, you have to use JEE's @Resource annotation, or use XML. By the way, the definition of the mySuccssView in Spring XML took 3 lines of code!!! Anyway, I was using WebSphere 6.1, and had to opt out of the @Resource because of classpath issues, so I had to use the XML config. The problem with the XML config is that @Controller servers two purposes: 1) defining a Role in the system, 2) defining the class as "I am available for use in a DI use" as part of classpath scanning and default autowiring. I wanted to set the value the value in XML, therefore the classpath scanning part of #2 was out of the question. To do that, I had to customize the component scanning with a Spring "context:exclude-filter."
The point of that example is that there are still plenty of gotchas that need to be ironed out. Guice is slightly ahead of Spring on those kinds of annotation gotchas. One of the most seemingly obvious abilities that Guice has is the import of key/value pairs into the module (a.k.a. "application context") as seen in this thread in the Guice News Group.
There's a lot more to this topic, but I hope that I've she some more light on this esoteric subject.
Jordan Zimmerman replied on Wed, 2008/11/12 - 5:42pm
Solomon Duskis replied on Wed, 2008/11/12 - 7:22pm
in response to:
Jordan Zimmerman
Here we go again. This argument is so 2004. I assume that you've read good old Martin Fowler's article on the subject.
DI moved away from Singletons and JNDI lookups. IHMO, DI's been a great boon for the quality and clarity of my code base. XML and annotation aren't code, they are indeed declarative configuration and possibly meta-programming.
You are correct. The term "Configuration" does apply. Usually I think about "Configuration" in the context of environment related setup. DI does make environmental configuration a lot simpler. However, it also adds in the ability to separate out how a particular class does its work and participates with other classes from how that class is exposed and how that class finds instances of other classes.
Yeah, at the end of the day DI is "Configuration", but its configuration that inherently replaces the code you as a developer have to write for the types of things covered by Creational and Structural Design Patterns.
Jordan Zimmerman replied on Wed, 2008/11/12 - 7:46pm
in response to:
Solomon Duskis
I've read most articles on the subject. Yes, the counter-arguments have been going on for a long time. That doesn't mean that the subject is settled.
Solomon Duskis replied on Wed, 2008/11/12 - 8:30pm
in response to:
Jordan Zimmerman
I've read most articles on the subject. Yes, the counter-arguments have been going on for a long time. That doesn't mean that the subject is settled.
[/quote]You're right. The subject of DI is not settled yet. But dismissing it as "just configuration" and something that "was done in software practice for years" doesn't seem to do it justice. We mortals do need simple phrases for complex concepts that DI solves like dependency management, environmental configuration and separation of concerns. There are other methodologies of solving those same needs. There are also different imlementations of DI that have plenty of merit.
With that said, comments like "Why not call this what we've always called this: Configuration. Everyone knows what that is." don't seem to lead the direction of the communal conversation towards "settling" the subject.
Jordan Zimmerman replied on Wed, 2008/11/12 - 9:43pm
in response to:
Solomon Duskis
Actually, I somewhat agree with you. Depenency Injection, however, is an unnecessarily obscure term. When I first heard I had no idea whatsoever what it meant. Automated Configuration is more descriptive. The name of the concept should give a clue as to the content of the concept. Having such an abstract name has allowed DI to mean whatever anyone wants it to mean.
Solomon Duskis replied on Thu, 2008/11/13 - 10:06am
in response to:
Jordan Zimmerman
Actually, I somewhat agree with you. Depenency Injection, however, is an unnecessarily obscure term. When I first heard I had no idea whatsoever what it meant. Automated Configuration is more descriptive. The name of the concept should give a clue as to the content of the concept. Having such an abstract name has allowed DI to mean whatever anyone wants it to mean.
[/quote]
DiP defines how objects interact with each other and that an object that encapsulates some behavior (DAO, service, UI and etc) should never (or rarely) look up or instantiate another behavior-driven dependency. Those dependencies can be either it another object or some configuration setting. DiP says that in order to get those dependencies, some external assembly system (either a framework, or hand-coding) should assemble the application and "inject" specific dependencies as needed.
In other words, you can adhere to the DI Principle without any configuration. It's the Dependency Injection Frameworks that use configuration to create a solution that adheres to DiP.
Ravi Hasija replied on Thu, 2008/11/13 - 11:23am
This is a great article. Led by example, and not dry by just providing theory. Simple, yet beautiful. Kudos to you for creating this. I have a firm grasp of what Spring and DI (in general) is.
I would love to have such articles on other topics like Hibernate, EhCache, Struts, EJB, JSP, etc to name a few. Probably they are already out there on this website. If not then, something to consider ;-)
Thank you so much!
Sincerely,
Ravi
Rick Hightower replied on Thu, 2008/11/13 - 12:10pm
Rick Hightower replied on Thu, 2008/11/13 - 2:35pm
in response to:
Ravi Hasija
Thanks Ravi. I really appreciate the positive feedback. It really helps. Thanks.
Bruno Sofiato replied on Fri, 2008/11/14 - 6:33pm
Cool article.
I personally don't like the current annotation usage model spread on the majority of the frameworks, guys configuration isn't meta-data. Annotations IMHO should be used to express semantical information within the code itself. The @Required annotations got it right. The ATMTransport is required by the AutomatedTellerMachineImpl class, thats an implementation detail of that class, the @Required is expressing a semantical info.
The @Autowired and the @Qualifier on the otherside are expressing config details. They are linking an property value to an named instance on the bean container. Should a class know which named instances will be injected on it's instances ? I think it should not.
Rick Hightower replied on Fri, 2008/11/14 - 11:08pm
in response to:
Bruno Sofiato
Bruno Sofiato replied on Sat, 2008/11/15 - 10:42am
in response to:
Rick Hightower
Yes, some objects were made to collaborate with others, but maybe the property declaration would provide this kind of info.
I agree that annotations are a popular aproach these days, maybe it's a consequence of this grudge against XML based configuration that is wildspread among the Java developer's ranks.
Just my 2 cents.
William Willems replied on Mon, 2008/11/17 - 5:54am
nitin pai replied on Mon, 2008/11/17 - 10:13pm
Rick - Thanks a ton. This timing of this article has been perfect to match with my intentions. I wanted to make my team understand the concepts of Spring such as DI, IOC, AOP etc. And you have just eased out my work since I do not have to compile the articles myself. This article is simply to the point.
Eagerly waiting for your further articles on Spring features. And if you require any help just let me know. I am on the same track too :)
George Jiang replied on Tue, 2008/11/18 - 9:43pm
The best introduction to Spring 2.5 DI. Better than those published Spring books.
Rick, when will the intoduction article to Spring AOP be out? Thanks.