J2EE patterns for inversion of control and dependency injection
I came across the J2EE patterns inversion of control and dependency injection while looking at
the J2EE framework, or lightweight container, Spring.
Both patterns describe how to connect application components and sit at the heart of containers such as
Spring, PicoContainer or Avalon.
Inversion of control
Inversion of control, or IoC, addresses tight coupling
between application components that are wired together in the application code. Suppose we have
a component named Acme that uses Foo and Hoo. Most often, the code handles the connection directly,
with Acme creating instances of Foo and Hoo.
class Acme ....
private Acme(){
foo = new Foo();
hoo = new Hoo();
}The drawback is that Acme is tightly coupled to Foo and Hoo. Suppose we have
a component named FooBar we want to use instead of Foo. Both implement the same interface.
We’d have to change the code to create a FooBar instead. This coupling means all such
changes depend on editing and recompiling the code.
IoC solves these problems by having the components wired
from outside. Acme, the consumer, doesn’t instantiate Foo and Hoo. Instead,
the instances are supplied to it externally.
class Acme ....
public void setFoo(FooInterface foo)..
public void setHoo(HooInterface hoo)..This is where those lightweight containers come in. They do the wiring from the outside.
The configuration, most often XML, determines which concrete instance is used for each connection.
The container uses that configuration to control the creation and setup of components. Inversion of control
allows objects to be created at a higher level and delivered straight to their consumer.
Dependency injection
Dependency injection goes hand in hand with IoC and deals with
supplying components to their consumer. There are three basic ways to do this.
Setter injection
Injection uses ordinary setters, the set methods you know
from the JavaBean model, for example. Spring uses this approach.
Constructor injection
Injection happens through the constructor. PicoContainer uses it.
Interface injection
Interface injection defines an interface through which the
component is configured. Avalon is a typical example.
There’s a lot of debate over which approach to choose. Interface injection sits somewhat at the margins,
so the main debate is about setters versus constructors. Both have advantages
and drawbacks, and comparing them is a subject for another article.
If you’re interested in the topic, I highly recommend the following sources,
which I drew on.
- Rod Johnson Introducing the Spring Framework
- Martin Fowler Inversion of Control Containers and the Dependency Injection pattern
- Jirka Fabián Understanding the IoC Pattern
- Mark Eagle Wiring Your Web Application with Open Source Java
Related articles
Related CZ Podcast episodes
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi and Filemon discuss Java 6 and web application frameworks. · Czech audio
- #1 · Vývojová prostředí v Javě
The first CZ Podcast episode looks at Java development environments. · Czech audio