I was wrong: Constructor vs. setter injection

Reading books or reference documentation is always good to get new ideas or to gain new insights.
While reading the Spring reference documentation, I realized I was wrong!

In one of my previous blog posts about Dependency Injection vs. Service Locator, specifically in the part “The final clash – Constructor vs. setter injection”, I said that I agreed with Martin Fowler.

Martin advocated the use of constructor injection as much as possible unless things are getting too complex. His advice is to use constructor injection to create valid objects at construction time. This advice originates from Kent Beck’s book Smalltalk Best Practice Patterns.
I myself have always used setter injection because that was the way I was taught to use Spring. But after reading Martin Fowler’s article, I agreed with having to use constructor injection more often.
In most circumstances, now I know I was wrong.

What are the problems with constructor injection?

No reconfiguration and re-injection

As the Spring reference documentation – Constructor-based or setter-based DI? states:

The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is a compelling use case.

Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code in a totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection.

Use the DI that makes the most sense for a particular class. Sometimes, when dealing with third-party classes to which you do not have the source, the choice is made for you. A legacy class may not expose any setter methods, and so constructor injection is the only available DI.

So indeed, using constructor injection when no setters exist, you cannot reconfigure the constructed bean by injecting new dependencies into it.
If you want to “reconfigure” the bean, you’ll have to construct a new bean instance using the new dependencies and discard the other one.

Circular dependencies

Another problem occurs when you’re having circular dependencies.
Again, the Spring reference documentation – Circular dependencies states:

If you use predominantly constructor injection, it is possible to create an unresolvable circular dependency scenario.

For example: Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection. If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.

One possible solution is to edit the source code of some classes to be configured by setters rather than constructors. Alternatively, avoid constructor injection and use setter injection only. In other words, although it is not recommended, you can configure circular dependencies with setter injection.

Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken/egg scenario).

While it’s not a recommended scenario, you could create a circular dependency using Spring. But not by using constructor-based injection. If you want to create a circular dependency, you’ll have to use setter-based injection.

I have an example of this, which can be downloaded through the following link: spring-setter-injection.zip
You’ll need Maven to build and run the example.

[UPDATE]
You’ll notice that the ConstructorBasedCircularDependencyTest does not fail.
Thanks to Mathew, I found a way of testing if the expected exception will occur. Instead of relying on the SpringJUnit4ClassRunner to create the ApplicationContext, I create the ApplicationContext myself inside the test method, and annotate the test method to expect the UnsatisfiedDependencyException, which wraps the BeanCurrentlyInCreationException.
[/UPDATE]

To end this post, I’ll quickly show how to use constructor-based injection and setter-based injection using Spring annotations.

Constructor-based injection:

@Component
public class A {
    private B b;

    @Autowired
    public A(B b) {
        this.b = b;
    }

    /**
     * @return the b
     */
    public B getB() {
        return b;
    }
}

Setter-based injection:

@Component
public class A {
    private B b;

    /**
     * @return the b
     */
    public B getB() {
        return b;
    }

    /**
     * @param b
     *            the b to set
     */
    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

So sometimes, when you get a new insight, you have to be able to acknowledge you were wrong about something.
I hope you all enjoyed reading this post.
Feel free to post your comments below.

Dependency Injection vs. Service Locator

Again, while reading through the Spring documentation, I came across this article of Martin Fowler.
I’ll try to give a summary of his article and my opinions about it.

Introduction

Every professional software engineer should know what dependency injection or inversion of control is about, but i’ll try to explain it for those who don’t.
I’ll use quite the same examples as Martin did in his article, which I’ll try to update a little. You can find a link to the source code at the bottom of this blog post (Maven is required to build the source).

Imagine you have to display a list of movies directed by a specified director.
I have an interface and a concrete implementation for finding movies.

public interface MovieFinder {
    public List<Movie> findAllMovies();
}
public class MovieFinderDummy implements MovieFinder {
    public List<Movie> findAllMovies() {
        List<Movie> movies = new ArrayList<Movie>();

        movies.add(new Movie("Gangs of New York", "Martin Scorsese"));
        movies.add(new Movie("E.T.: The Extra-Terrestrial", "Steven Spielberg"));
        movies.add(new Movie("The Aviator", "Martin Scorsese"));
        movies.add(new Movie("Indiana Jones and the Temple of Doom", "Steven Spielberg"));
        movies.add(new Movie("Jurassic Park", "Steven Spielberg"));

        return movies;
    }
}

To list the movies with a specified director, the following code is used:

public class MovieLister {
    private MovieFinder movieFinder;

    public Movie[] listMoviesDirectedBy(String director) {
        List<Movie> allMovies = movieFinder.findAllMovies();
        for (Iterator<Movie> iterator = allMovies.iterator(); iterator.hasNext();) {
            Movie movie = iterator.next();
            if (!movie.getDirector().equals(director)) {
                iterator.remove();
            }
        }

        return allMovies.toArray(new Movie[allMovies.size()]);
    }
}

Especially the MovieFinder at line 02 is of importance here.
You need to have a way to provide the concrete class that will be used for this MovieFinder instance.

Basic solution

What you can do is specify the MovieFinder‘s concrete class in the MovieLister‘s default constructor, like this:

public class MovieLister {
    private MovieFinder movieFinder;

    public MovieLister() {
        movieFinder = new MovieFinderDummy();
    }

    ...

You’ll see. The code works. But we’ll soon be in trouble when sharing this service with other developers who are going to use it for their own projects.
If another developer also wants to use the MovieLister, but wants to get his movies from a text file, a database or XML, he’ll have to change the code of the default constructor.
Of course in our case, he can’t change the constructor. We created the service and packaged it in a JAR without releasing the source code. So he cannot change what kind of MovieFinder is used in the MovieLister. Our code isn’t configurable and reusable.
The MovieLister class is dependent on both the interface and the implementation of MovieFinder.
Actually, you must try to make it only dependent on the interface.

Dependency injection

That is where dependency injection comes into play.
The idea about dependency injection is that the class itself that is going to use the (MovieFinder) dependency is not responsible for instantiating a concrete implementation of the interface, but the dependent concrete implementation is given to the class by some other object. Martin calls that object an assembler.
This way, the MovieLister class isn’t dependent on the MovieFinderDummy implementation anymore, but only on its MovieFinder interface (it doesn’t have to do an import of the concrete implementation class).

There are several types of dependency injection:

  • Constructor injection
  • Setter injection
  • Interface injection
  • Field injection: This one’s new, using annotations on fields, parameters but also on constructors or setters

You can read all details about each type of injection in Martin Fowler’s article.
I’ll only give an example of setter injection using the Spring framework.

Setter injection with Spring

Taken from the SpringSource website:

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications – on any kind of deployment platform. A key element of Spring is infrastructural support at the application level: Spring focuses on the “plumbing” of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments.

Spring includes:

  • Flexible dependency injection with XML and annotation-based configuration styles
  • Advanced support for aspect-oriented programming with proxy-based and AspectJ-based variants
  • Support for declarative transactions, declarative caching, declarative validation, and declarative formatting
  • Powerful abstractions for working with common Java EE specifications such as JDBC, JPA, JTA and JMS
  • First-class support for common open source frameworks such as Hibernate and Quartz
  • A flexible web framework for building RESTful MVC applications and service endpoints
  • Rich testing facilities for unit tests as well as for integration tests

You can use Spring to wire up all your dependencies using configuration written in Java code, XML or annotations.
Nowadays, Spring supports setter, constructor and field injection. Using XML most people tend to use setter injection. When using annotations, field injection will be preferred.

I’ll show the example using both XML and annotation-based configuration.
Using annotations, you’ll have to change your code to have a different kind of MovieFinder implementation injected into the MovieLister class. You can use qualifiers, but if the third party component developer provided a MovieFinderFileDummy annotated as a @Service with qualifier “main”, you’ll still have to change the @Autowired @Qualifier annotation to use your own qualifier name inside the provided MovieLister class.
Using XML, your configuration is completely separate from your Java code, so you can completely change the configuration at will without altering the source code.
(Correct me if I’m wrong at this point)
You can also use a mix of annotations and XML configuration. For example, define your MovieLister class in XML where you define the name or the qualifier of the MovieFinder bean to use, and use the @Service and @Qualifier annotation in the MovieFinder to specify your concrete implementation.

Spring XML configuration

Using the same example as above, I’ll now use Spring XML configuration.
I’ve changed the name of MovieFinderDummy to MovieFinderXmlDummy to clearly separate both examples.
The MovieLister doesn’t use a constructor anymore for instantiating the MovieFinder implementation, but uses a setter for injection.

public class MovieLister {
    private MovieFinder movieFinder;

    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    ...
}

My Spring XML configuration looks like the following listing:

<?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-3.1.xsd">

	<bean id="movieFinder" class="be.stesch.movie.spring.xml.MovieFinderXmlDummy" />

	<bean id="movieLister" class="be.stesch.movie.spring.xml.MovieLister">
		<property name="movieFinder" ref="movieFinder" />
	</bean>
</beans>

Here I declare a movieFinder bean of type MovieFinderXmlDummy.
I then declare the movieLister bean of type MovieLister to use the movieFinder bean as it’s dependent property. This way Spring will inject a MovieFinderXmlDummy instance in the MovieLister.

The Client then uses the ClassPathXmlApplicationContext to load the Spring application context to be able to get the MovieLister and list all movies with the specified director.

public class Client {
    private static final String MOVIELISTER_BEAN_NAME = "movieLister";

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "META-INF/config/xmlApplicationContext.xml");

        MovieLister movieLister = applicationContext.getBean(MOVIELISTER_BEAN_NAME, MovieLister.class);
        Movie[] movies = movieLister.listMoviesDirectedBy("Steven Spielberg");
        ...
    }
}
Spring annotation configuration

When using annotations, my Spring application context XML configuration file get’s reduced to the following listing:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<context:annotation-config />
	<context:component-scan base-package="be.stesch.movie.spring.annotations" />
</beans>

As you can see, I don’t define any beans anymore in this XML. I just define that annotations will be used to configure the Spring container, and where to scan for candidate beans.
Again, here I renamed the MovieFinderDummy to MovieFinderAnnotationDummy for clarity and separation in execution.

@Service("movieFinder")
public class MovieFinderAnnotationDummy implements MovieFinder {
    ...

The MovieLister will now be declared as a Service component where the MovieFinder dependency will be Autowired.

@Service("movieLister")
public class MovieLister {
    @Autowired
    @Qualifier("movieFinder")
    private MovieFinder movieFinder;

    ...

You don’t really need to give a name with the @Service annotation, or use the (Spring based) @Qualifier annotation in the MovieLister class, but it’s just to use the same bean names as in the XML example. Without an @Service name and without an @Qualifier Spring will use the class types to perform dependency injection.
The Client works the same, except for using a different Spring configuration file based on annotations.

public class Client {
    private static final String MOVIELISTER_BEAN_NAME = "movieLister";

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "META-INF/config/annotationApplicationContext.xml");

        MovieLister movieLister = applicationContext.getBean(MOVIELISTER_BEAN_NAME, MovieLister.class);
        Movie[] movies = movieLister.listMoviesDirectedBy("Steven Spielberg");
        ...
    }
}

As said, you can mix and match. Make the MovieLister an annotation configured @Service, declare the MovieFinder‘s concrete implementation in the configuration XML itself and don’t use annotations in the MovieFinder implementation class.

If you want to minimize your dependency (import statements) on Spring, you could also use the JSR 330 Standard annotations like @Named instead of @Service, and @Inject instead of @Autowired, like shown in my downloadable source code.
This way, the only import of the Spring framework resides in the Client class, because there your Spring application context has to be set up.
If you create a web application and reference the applicationContext.xml file in your /WEB/INF-web.xml, then you don’t even have a single Spring import in your source code, while still working with Spring.

Service Locator

Now that you have a complete view on dependency injection and Spring, let’s move on to the Service Locator pattern.
The Service Locator has the same goal as dependency injection: to remove the dependency to the implementation from the calling class.
As Martin Fowler’s article states:

The basic idea behind a service locator is to have an object that knows how to get hold of all of the services that an application might need. So a service locator for this application would have a method that returns a movie finder when one is needed.

I like the idea of having a dynamic Service Locator, with a Map containing all services by key. But I can also agree with Martin’s argument that it’s not explicit. The only way of knowing what services are available is by looking at the keys stored in some file or class. So as an example, I made a mix of both.

This is my Service Locator’s code:

public class ServiceLocator {
    public static final String MOVIEFINDER_SERVICE = "movieFinder";

    public static final String MOVIELISTER_SERVICE = "movieLister";

    private static final ServiceLocator instance = new ServiceLocator();

    private final Map<String, Object> services = new HashMap<String, Object>();

    private ServiceLocator() {
    }

    void loadService(String key, Object service) {
        services.put(key, service);
    }

    public static ServiceLocator getInstance() {
        return instance;
    }

    public Object getService(String key) {
        return services.get(key);
    }

    public MovieFinder getMovieFinder() {
        return (MovieFinder) getService(MOVIEFINDER_SERVICE);
    }

    public MovieLister getMovieLister() {
        return (MovieLister) getService(MOVIELISTER_SERVICE);
    }
}

You can see that my Service Locator is a Singleton that has a Map containing two services. The MovieFinder service and the MovieLister service.
To make the ServiceLocator class testable, and to be able to provide the ServiceLocator with different service implementations, I also use a separate Assembler class loading (or putting) serivces in the ServiceLocator‘s services Map.

public class Assembler {
    private static final Assembler instance = new Assembler();

    private Assembler() {
    }

    public static Assembler getInstance() {
        return instance;
    }

    public void configure() {
        ServiceLocator.getInstance().loadService(ServiceLocator.MOVIEFINDER_SERVICE, new MovieFinderServiceLocatorDummy());
        ServiceLocator.getInstance().loadService(ServiceLocator.MOVIELISTER_SERVICE, new MovieLister());
    }
}

I think you can see this Assembler somewhat in the same way like setting up the Spring application context. It instantiates the services, and makes them available to the calling environment (in this case, through a Service Locator).

If the services don’t contain any state that should be retained while working in a class (and they shouldn’t!), then you can call the Service Locator every time you need a service, instead of storing it somewhere in it’s calling class.
The main class (Client) should still call the Assembler (like creating a new ApplicationContext) to configure the application and load services in the Service Locator.

public class Client {
    public static void main(String[] args) {
        Assembler.getInstance().configure();

        MovieLister movieLister = ServiceLocator.getInstance().getMovieLister();
        Movie[] movies = movieLister.listMoviesDirectedBy("Steven Spielberg");
        ...
    }
}

The final clash

Dependency Injection vs. Service Locator

Why all the fuzz of manually creating a Service Locator solution while you have dependency frameworks available like Spring?
Well, you’ll have to decide based on your requirements, your project and your knowledge.

The Service Locator and dependency injection both have their pro’s and their con’s or implications. Both cases make the application code independent of the concrete implementation of the service interface.

  • With dependency injection, no explicit request is required. The service “appears” in or is given to the application class.
  • Dependency injection tends to be hard to understand and hard to debug.
  • With Service Locator every “user” of a service has a dependency on the Service Locator. If this is a problem, use dependency injection.
  • Using dependency injection, dependencies can be more clear.
    With Service Locator you’ll have to search for every use. With dependency injection you can just read the constructor or the setters. Your usage depends on the nature of the application.
  • Dependency injection might make testing easier, but a Service Locator can also be testable if it is correctly designed.
  • If your code is going to be used in applications that are outside the control of the developer, Service Locator is out of the question. Use dependency injection.

My opinion here is that a dependency injection framework like Spring has evolved so much, that issues you might be having with dependency injection are irrelevant, except perhaps being harder to understand and harder to debug. Spring has it’s own testing framework, which is really an easy framework. It offers configurable dependency injection in code using Java, annotations or in XML configuration files. And it offers an entire platform of support classes and API’s to use enterprise grade components in an application that’s not running on an enterprise application server.
Why re-invent the wheel (design a Service Locator framework) if you can use Spring easily?

Constructor vs. setter injection

I’ve always used setter injection. I supose I was taught it that way or was used to it like that. But after reading Martin’s arguments, it makes sense.
He suggests using constructor injection because you need to have valid objects at construction time. So perform the injection using the constructor. Apparently, this advice originates from Kent Beck’s Smalltalk Best Practice Patterns: Constructor Method and Constructor Parameter Method.

Using constructor injection allows you to hide immutable fields from users of your class. If you don’t want the MovieFinder to be changed or set in the MovieLister class while using the application, then don’t create a setter for it. You then have to use constructor injection to use the dependency. This way you can encapsulate the dependencies in your class.
A disadvantage of constructor injection is that constructors might get a lot of parameters quite fast, or that you have to create a lot of overloaded constructors for every way the object might be created. If this is the case, Martin suggests resorting to setter injection. So, first use constructor injection, until things become too complex. Then change that class to setter injection.
I follow him in this aspect.

Code vs. configuration files, and separating code from usage

There, I follow his advice as well, more or less.
Up untill these days I only used dependency injection (Spring) using XML configuration files (in commercial projects). I like this way of configuring an application because it’s completely separate from your code. Some third party user might want to change the way you application works by changing the XML configuration. If a client wants to use Hibernate or JPA instead of the JDBC code that you have written, he just has to create a Hibernate / JPA implementation and change the dependencies in your persistence layer to his Hibernate / JPA DAO’s.
For smaller projects, or projects that stay under your own control, programmatic configuration can be preferred. XML configuration tends to get cluttered and hard to read and maintain.

Nowadays, this is where annotations come in. You can use programmatic configuration in the Java file where it belongs, without having to create a whole bunch of separate XML configuration files.
If your project is going out of your hands at the end, it can be better to make use of XML configuration.

To conclude

  • These days, Service Locator isn’t of much use anymore, except in very small proprietary projects. For the rest, use a good dependency injection framework.
  • Prefer constructor injection over setter injection to have valid objects at creation time, unless the constructor becomes too complex.
  • If your project is going out of your hands or tends to change a lot, use XML configuration. Otherwise, use code or annotations to configure your application.

I hope you have enjoyed this blog post.
As always, please post your comments and advice.
You can find the source code on my Public DropBox: movie-demo.zip

The Open-Closed Principle: The heart of object oriented design

I have a question for you guys and girls.

This morning, I was reading through the Spring documentation about the Web MVC framework.
In a side-note, “Open for extension…”, SpringSource referred to a paper about the design principle “Open for extension, closed for modification”.

A key design principle in Spring Web MVC and in Spring in general is the “Open for extension, closed for modification” principle.

Some methods in the core classes of Spring Web MVC are marked final. As a developer you cannot override these methods to supply your own behavior. This has not been done arbitrarily, but specifically with this principle in mind.

I found this comment somewhat contradictory to the Open-Closed Principle.

I read the paper of (Uncle) Bob Martin, which can be found at the link The Open-Closed Principle, and wanted to share my thoughts with you.

The paper gives a very good and understandable explanation about this OOD (Object Oriented Design) principle.
It’s all about abstraction, encapsulation and design for change, which are principles that lie at the heart of OOD.
You have to write your code in such a way that, if you need to change the behavior of your application, you just extend instead of modify your existing code base. In the most ideal circumstance, you should not touch any lines of code that you have written in the past.

A procedural design

Bob Martin uses shapes as an example. You could write code like the following listing to create a Client-Server application that draws shapes.

public class Shape {
    ShapeType type;
}
public class Circle extends Shape {
    public Circle() {
        this.type = ShapeType.CIRCLE;
    }

    double radius;

    Point center;
}
public class Server {
    void drawSquare(Square square) {
        System.out.println("I'm drawing a square");
    }

    void drawCircle(Circle circle) {
        System.out.println("I'm drawing a circle");
    }

    void drawAllShapes(List<Shape> shapes) {
        for (Shape shape : shapes) {
            switch (shape.type) {
            case SQUARE:
                drawSquare((Square) shape);
                break;
            case CIRCLE:
                drawCircle((Circle) shape);
                break;
            }
        }
    }
}

You can see immediately that if you need a new kind of shape, you need to create a new class for this shape (which is good), but you also need to modify the entire Server class. You have to add another draw method, and you need to change the switch in the drawAllShapes method.
So, a lot of changes in your existing code are necessary just to use a new kind of shape.

An Object Oriented Design

To be able to add new shapes without having to change your existing code base, you can do the following:

public abstract class Shape {
    public abstract void draw();
}
public class Circle extends Shape {
    private double radius;

    private Point center;

    // Getters and setters

    @Override
    public void draw() {
        System.out.println("I'm drawing a circle");
    }
}
public class Server {
    public void drawAllShapes(List<Shape> shapes) {
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}

As you can see, your code becomes much more concise, readable and when you want to add a new kind of shape, you just extend the Shape class and implement the draw method in that new class. “Open for extension, …”.
Also, you don’t need a ShapeType attribute anymore, because the new shape class IS the type!

This principle goes a lot further, but you can read the rest in Bob Martin’s excellent paper.

My question about this matter

What does SpringSource mean with “Some methods in the core classes of Spring Web MVC are marked final. [...] This has not been done arbitrarily, but specifically with this principle in mind.

If the Open-Closed Principle stands for “Open for extension, …” what do final methods have to do with this principle?
Final methods cannot be overridden in subclasses. Thus that behavior cannot be extended. It is closed for modification but I thought that had to do with not touching the existing code base, while being able to change it’s behavior by extending classes and overriding methods.

Can you guys and girls elaborate on this with me?
Feel free to post your comments to this blog post.

As usual, you can find the source code at the following link: shapes-demo.
You won’t need Maven to build this demo. Just extract it in your Eclipse workspace, and import the existing project. You might need to change the classpath to add your own JRE System Library.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: