Constructor Injection and Field Injection Misconception Cleared

Constructor Injection and Field Injection Misconception Cleared:-

In this post i am gonna talk about Constructor and Field injection . It came out of a fight between me and my friend that Constructor Injections are better and we had a pretty much bad fight. It all started with this line in my code .

Lemme tell you one thing before we deep dive Constructor Injection and Field Injection is a debatable topic .

Let me know in comments what do you think .

@Autowired
private ClassA A;

I used to be a huge fan of this piece of line . But I have been mistaken and I admit it .

I was aware of the dependency injection types  , but those differences seem to me good for interview or too much theoretical. It is possible that  I didn’t want to understand those in a deeper level .

Most of us are pretty much confident about writing a cleaner code and above line does makes our code clean . 


What Is Wrong :-

Using DI Containers we make sure that a class doesn’t have to manage its own dependencies , but here we are making our class to manage its own dependencies. Class should be more independent .Using a Constructor Injection here makes more sense.

Lets think of a scenario where your Service class has a field injected .Think a moment While writing test cases can you have a look a class and figure out the dependencies needed for the class ?? . No You cant , you have to go and explore the class , then you will be able to find out the dependencies used in your classes.

Now again , once you want to assign some mock values to your  private fields it is not easy .You have to setup a spring Context as Spring  can inject dependencies into private fields . You might need to use reflection in worst cases .

I know most people says reflection is common now a days , but my friend doing these , The Whole purpose of dependency injection goes for  a toss . As , the main purpose of DI was to write code that is easier to test and Write code that is highly decoupled.

Summarize What happens to Following Code :-

class MyService{
 
  @Autowired
  private ClassA A;
  
  public void doSomething() {
    A.doSomething();
  }
}

So basically what you are saying over here is :-

“I have this class with private state, to which I have attached @Autowired annotations, which means that the state can be automatically changed by some agent from the outside, even though my state has all been declared private.” 

Your JUNIT test cases starts breaking here as you will be doing below 

MyService service= new MyService();
service.doSomething(); // -> NullPointerException

You are allowing anyone to create a instance using default constructor and change state of your object which is not good.

How to Solve this :-

Well , we are going forward to explain Constructor Injection but  in terms of usability . Lets have a look at the solution of the above problem .

class MyService{
 
  private final ClassA A;
  
  @Inject
  public MyService(ClassA A) {
   
    this.A= A;
  }

  public void doSomething() {
    A.doSomething();
  }
}

Short Summary :-

  1. No null pointer as the class has the mandatory dependency provided at the time of creating object.
  2. Final fields adds too immutability here .
  3. As a consumer i know what all dependencies are required before creating object of this classs.
  4. Looks like a lot of code ? We can use Lombok to remove this boilerplate 
  5. If you feel you classes has a lot of dependencies , you probably need to rethink about your design and segregate your classes in different modules.




Have a Look In Case you Have a Frugalisminds !