Spring IoC: The Java Enterprise drug
By now I have used Spring in a significant number of projects, in fact I’d go as far as to say that Spring has become as indispensable to ‘Enterprise’ projects as an application server. Well, at least to me and most of the people I know and work with. The most used Spring feature by far, if not the only one in most cases, is Spring IoC, AKA Dependency Injection.
I’ve seen a working attempt to programmatically configure Spring (XML configuration files have been the uncool kid in the post-Rails Java world as you might have noticed). Cool as this might sound, it didn’t really work if you ask me. It was too much work and we ended up with a castrated version of Spring IoC in which you could only use name based constructor Dependency Injection and that was about it - do correct me if I’m wrong, Ashok, Nick, Simon and co. Spring was built to be configured through XML files and moving away from that is not a trivial task. We all know the nightmares of maintaining numerous huge XML configuration files, which brings us to the main point of this post…
The most common mistake I’ve seen developers who have just been introduced to Dependency Injection do - including myself, more than once - is overusing it. The advantages that come out of it cannot be ignored. The loose coupling between objects is fantastic. The code looks much cleaner. Unit testing distinct class responsibilities in isolation suddenly becomes a breeze. Just mock or stub an external dependency, pass it through the constructor or a setter method and you don’t have to worry about its behavior in relation to the class you’re testing any more. Devs fall in love with this aspect of IoC so much that many a time I have actually seen classes, as opposed to interfaces, being injected. Which of course breaks the whole concept of IoC.
It is this addiction to injecting everything (what I like to call the Nikki Sixx anti-pattern…) that ultimately leads to huge xml configuration files and introduces a number of other code smells along the way. See, in my opinion, it’s not XML configuration’s fault at all. It is just lazy, bad, something-stinks-in-here design. It leads to the Impl smell, you know the one, where every single class has a corresponding interface. This is not what interfaces are about. Interfaces, in my opinion, are by definition, points of access through which a bunch of collaborating classes communicate with the rest of the world.
I seriously dislike adding extra code to classes only to accommodate unit tests. For the same reason, I think IoC should be really carefully thought out and avoided until the design has been considered more thoroughly and actually makes sense. If I’m having trouble testing a class in isolation from its collaborators, I much prefer stubbing them out by extending them in a private class inside the unit test and make them behave as I would expect to, instead of extracting an interface and injecting it. If I’m injecting more than two dependencies to a class, there has got to be something I’m doing wrong. Time to revise my design. I push myself hard to use interfaces and IoC only at package level. One of the greatest features of IoC is seamless component exchange without affecting anything that’s depending on the component’s behavior. The key to this is dedicating a bit more consideration as to what qualifies as a component and how clear the component is about its responsibilities.
If only components are wired with IoC, then the XML file will not only be seriously leaner and easy to manage, it will also be a great way to document and understand the manner in which the different parts of the application are communicating and interoperating. Not to mention we will end up with a seriously better designed application the best of us would be proud of. As a 70’s ex rock star who’s managed to stay alive to this day would probably tell their kids today: Go out, have your fun, but don’t go too far, because I’ve seen it happen and it’s nasty.
Digg some recreational fun in Java

June 17th, 2006 at 1:52 pm
I have a few questions:
-Have you tried using dependency injection without a framework? What benefits does Spring bring over just using the “new” operator?
- Did the people who trying to programmatically configure Spring consider just using the “new” operator to manually wire their objects together?
- With regard to, “I much prefer stubbing them out by extending them in a private class inside the unit test and make them behave as I would expect to”, have you had any problems maintaining code that uses that technique a lot? What do you do when the class that you’ve stubbed out changes and you then have to track down all of it’s sub-classes in the tests?
- With regard to, “Spring has become as indispensable to ‘Enterprise’ projects as an application server”, do you think this is a good thing? Does it help you higher-quality systems quicker?
June 17th, 2006 at 2:34 pm
Hey Ade, long time no see. All good points. I take it you’re having second thoughts about IoC?
-Have you tried using dependency injection without a framework? What benefits does Spring bring over just using the “new” operator?
IoC, being sort of a glorified Factory Pattern, offers most of Factory’s benefits. For instance, single point of replacing, say, XmlRepository with a HibernateRepository implementation to Repository. Imagine if XmlRepository has been instantiated using ‘new’ all over the place. This should also apply to your second question.
On stubbing external dependencies… Yes, it’s not a silver bullet and should be used with caution. However, if the system has been well designed, the internal implementation of the stubbed class’s services should not affect the stub and certainly should not affect the test that’s making use of it. If it has a method, getTotal() which is being used by the class under test, it’s just the result of this method that we care about and the way this is being calculated should not matter in the scope of the test in question.
- … Does it help you higher-quality systems quicker?
IMHO, it does help organize the codebase and replace components’ implementations with little pain. This replacement is not required that often, but when it is, Ioc can play a major role to an easy transition.
I suspect you already have your version of the answers to the above questions, and I would really like to hear it.
June 18th, 2006 at 12:57 am
Well you asked for it…
Let me reflect: I think you’re saying that IoC is all about functional decomposition. And that people are using IoC at too low level of granularity.
But who defines what a component is? It seems like a subjective decision, like deciding whether a virus is “alive” or not, or whether chimpanzees are “intelligent”. Is this the role of an “architect”?
Secondly, how do you respond to cross-cutting concerns; design constraints such as logging, security, remoting, asynchrony, transaction control, new domain models, etc.?
Objects have two responsibilities - the first to its callers, and the second to the environment in which it operates. So I like IoC as a way of a class declaring to the world to “treat me like an object”. Objects need to become more “environmentally” aware.
Now I think that your discussion of interface vs. implementation misses out on one of the core OO concepts: message passing. Even in the early stages of a project, injection is not just about functional decomposition, it is about deferring choices of the medium through which a message can pass. Some people call this “context”.
By using IoC only at the component level, you prevent control over the fine grained message passing, and this leads to cross cutting concerns being implemented in multiple places.
Anyway, a few points:
- Using classes breaks the whole concept of IoC, and
- …leads to the Impl smell, you know the one, where every single class has a corresponding interface
Both these statements imply a code-base in transition. The first: an interface hasn’t been defined yet, but at least there is a seperation of complexity. But even when injecting classes rather than interfaces, you still don’t guarantee the actual implementation. There are various interceptors that can sit between the class under test and the injected class.
The second: Once you’ve defined an interface, you only have one implementation. But one assumes that you’ve introduced an interface for a reason.
- Castrated version of Spring IoC…
It wasn’t just programmatic configuration of Spring. It was the use of a fluent interface to express the wiring. Given that we’d changed container at least once on the project, I think this was quite elegant.
-…in which you could only use name based constructor Dependency Injection
Spring supports multiple patterns of injection, but I think it’s ok to narrow this down on any given project so that there is a consistent metaphor. In this case we are enforcing the “Good Citizen” concept. But exceptions are still possible…
-I think IoC should be really carefully thought out and avoided until the design has been considered more
I’ve always felt that “Design” isn’t a thing. It is a process. Thus talking about the “design” is a bit like talking about the “integration”. I think that design is about considering options. At the end of a good design process you have something that satisfies all the constraints. So let’s do it all the time. But lets use consistent metaphors to enable that design process, in the same way that we can use TDD as a standard approach the unit, integration, and acceptance levels
June 18th, 2006 at 6:38 pm
Spring framework has become indispensable for me too, but I only use the Ioc funcionality.
http://bloggingg.blogspot.com/
June 28th, 2006 at 3:06 pm
Nice article!
You should consider looking closely at Hivemind, which is a very nice IOC framework that avoids the mess Spring configuration can be, in an elegant way.