dagblog.
← Archive

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.

Medium version

Related articles

Related CZ Podcast episodes