Spring 2.5: Dependency Injection that doesn’t hurt
Filed Under (Architecture, Java, Spring) by Leonardo Borges on 07-12-2007
Dependency injection - DIÂ - Â is a great thing. Really. The hability to tweak implementations without touching your code is awesome and the DI frameworks, like spring, saves you a lot of coding. No more service locators stuff.
But, and there is always a but, you’re left with a bunch of XML configuration. And I hate it. Not that XML files are bad… the thing is that everything nowadays has its own set of XML configurarion files. And Spring is not different.
Let’s take a look at a simple example on how dependency injection is handled in Spring.
Imagine you have a domain object called Invoice that, among other things, is somewhat defined like this:
[java]
public class Invoice {
//normal attributes and getters/setters
public void sendByEmailTo(String address) {
//code to send invoice by e-mail
}
}
[/java]
You have a method to send a certain Invoice through e-mail, probably to some customer. This method would basically do some processing, maybe formatting strings, and then, ideally, delegate the send e-mail task to someone else. Probably a infrastructure service or something similar, that I will call EmailService. This object knows how to do the low level stuff like connecting to the SMTP server and so on. So we need this object, we depend on it. To express this dependency, the Invoice code would change to this:
[java]
public class Invoice {
//normal attributes and getters/setters
private EmailService emailService;
public void setEmailService(EmailService service) {
emailService = service;
}
public void sendByEmailTo(String address) {
//code to send invoice by e-mail
}
}
[/java]
This way the Invoice class is prepared to be injected with its only dependency using Spring. Now, what you would have to do is to declaratively express this dependency to the Spring container, so it can settle things for you. This is done through its XML configuration file, often called applicationContext. Below is the snippet of the file relevant to this example:
[xml]
[/xml]And that’s it. Upon initialization Spring will use this XML file to discover that the Invoice object depends on the EMailService object and inject it using the setter method we created before.
The problem is: If we have 50 domain objects that depends on 10 service objects that depends on anything else, we would end up in a XML forrest with at least 60 bean definitions.
Of course you can break this creating smaller XML files, but they are still XML files with bean definitions. Well, with Spring 2.5 we have a better option: We can use annotations!
In this new release, Spring use its own set of annotations to resolve object dependencies without XML. Let’s see how this thing works.
Our previous Invoice object would change to this:
[java]
public class Invoice {
//normal attributes and getters/setters
@AutoWired
@Qualifier(”myEmailService”)
private EmailService emailService;
public void setEmailService(EmailService service) {
emailService = service;
}
public void sendByEmailTo(String address) {
//code to send invoice by e-mail
}
}
[/java]
Let’s explain this change. The @AutoWired annotation tells spring that it should automatically wire dependencies based on its type, in our case, EmailService. But we take it a step further and choose which object to inject based not only on its type, but based on its name, with the @Qualifier annotation.
 Hmm… you may be asking now - But where did we say the object name is myEmailService?
 Okay, the other leg of the magic is on the @Component annotation:
[java]
@Component(”myEmailService”)
public class EmailService {
//methods
}
[/java]
With this annotation, you register a new component available for injection within the Spring container. This way, you don’t need to put neither the Invoice objects, nor its dependencies in the xml files. Pretty, huh?
But one question remains: How the hell spring knows about this annotated classes?
This is the one-million question and the answer is simple. You do need an XML file, but just to tell spring where to look for annotated classes, this way:
[xml]
[/xml]
The first clause sets the container to support annotation based configuration. The second one, component-scan, defines the base package where Spring should look for anotated classes within your project. That’s how it will be able to discover who needs who and who is a eligible component for injection.
You are really left with a small, tiny, piece of XML. Much more clean, elegant and much less XML to type.



Thanks for demonstrating the use of annotations. I agree with you that XML configuration files can grow out of control and become a pain to maintain.
But this autowiring leads to a question about testing. One of the main benefits of IoC is that it allows you to change the dependencies by editing non-code files, and this facilitate testing of classes by using stubs or test harness instead of the real dependencies. I wonder how annotations play into this.
We can use annotations for the real application, and full XML files for testing, but then we go back to the issue of XML file maintenance (at least here we would have to deal with half as much config files)
Ross - in your unit test you get the wired-up bean from the Spring context and then just call a setter to replace its dependency with a mock. Easy.
Invoice.setEmailService(myStub). Done.
Ross and Dan, thanks for the comments.
Ross, Dan is right. You can just replace the instance with your mock but, since you get the wired-up instance, maybe you don’t even need to do that.
If you can share an example, I can try to help more.
Ross, Dan, Leo. I think we can use a better aproach to the test problem. We can use write our code as interface based, so we inject interfaces. While testing, we provide in classpath mock implementations of that interfaces. Spring will find the interfaces implementations and use them.
One thing you don’t explain, and which pretty much every single web article doesn’t explain, is how do you get an instance of (per your example) Invoice? You obviously don’t do an Invoice invoice = new Invoice(). Unless Spring integrates into the VM and intercepts the ‘new’ keyword (yes, I’m being sarcastic). Seriously though, outside of the little Hello World apps, why are there no examples showing how you actually create an instance of the object that is being injected by Spring. I don’t want a Singleton. I want, for instance, a new instance of Invoice each time. Does nobody know hence they don’t have that in their illustrations. Not sure I’ve seen a single example yet.
Hey Darryl,
Actually you are not being sarcastic at all. We can have the Spring framework kind of listening to the “new” keyword. (Actually, the object instantiation process itself).
This is done through aspects. But if you don’t wanna have the hassle of using aspects in your app, you better have your model as an “Anemic Model” and inject your dependencies into your controllers and services.
Anyway, if you think it’s valid, I can prepare another post about how to do it using aspects. Just tell me what you think. I’ll be very happy to do so!
Thanks for your comment.
Lecturas…
Sobre Injeccion de dependencias para objetos de negocio y otras cuestiones de Spring…
Notas sobre Configuracion en Spring…
Si bien esta pagina no tiene mucho información, el objetivo de la misma es registrar tips, usos comunes de Spring para resolver cuestiones de configuración, etc…….
AspectJ con Spring…
TODO Ver una estrategia razonable para hacer que los objetos de dominio puedan acceder a la Configuracion…