Pages

Wednesday, September 3, 2014

Dependency Injection to Private Fields?

I recently spent a lot of time reading up on dependency injection in Java using Spring framework and Java EE.  I was rather surprised to see so many examples showing dependency injection to private fields. In fact, I was surprised it was even possible.  Here's the kind of example, I'm talking about:


public class MyClass {
     @Autowired
    private List list;

    public MyClass() {
     }
}

I sincerely hope these are just thoughtless examples designed to optimize page real estate and not customary practice. 

Here are 3 reasons why I will be avoiding injecting dependencies to private fields and prefer constructor injection and setter injection instead:

1) It Violates Encapsulation

The idea of encapsulation is that we limit the ways that components can interact through an interface (whether that interface is just the API provided by the class or an explicitly defined interface that the class implements).  Private data is an implementation detail that no other class should care about or know about, including any frameworks or dependency injection containers.

2) It Obscures Class Dependencies

If you were to look at the javadoc output of a class that relies on dependency injection to a private field, you would have no idea that the class depends on something.  But on the other hand, if there were constructor argument for the dependency, it would be clear.

3) It Promotes Tight Coupling

By using private field dependency injection, you are saying that reflection is necessary to use this class.  That is a rather bold and committal statement.  Reflection was created to support a few specialized uses and is not for everyday use like initializing an object in a unit test.

Using constructor or setter injection is simple and easy to do.  It only requires writing a few trivially easy lines of code:

public class MyClass {

      private List list;

      @Autowired
      public MyClass(List list) {
           this.list = list;
      }
}

So its hard to argue that private field dependency injection is really saving you any effort.

No comments:

Post a Comment