Home > Net >  @Autowired or private final
@Autowired or private final

Time:04-02

My question is simple. Which approach is more efficient? 

method 1:

 @Autowired
 private CustomerRepository customerRepo;

method 2:

private final CustomerRepository custormerRepo;
 
public StudentService(CustomerRepository customerRepo) {
         this.customerRepo = customerRepo;
}

As I see the DI in the method2 is more recent. But I wanted to ask you which one should I use?

CodePudding user response:

TL;DR: Method 2 is much more flexible.

Method 1 is an example of field injection and method 2 is an example of construction injection.

Field injection has some drawbacks that constructor injection avoids. Here are some advantages of constructor injection:

Immutability:

You can't do this is plain Java:

@Autowired
private final CustomerRepository customerRepo;

// No constructor that sets "customerRepo".

So, Spring offers constructor injection:

private final CustomerRepository customerRepo;

@Autowired
public StudentService(final CustomerRepository customerRepo) {
  this.customerRepo = customerRepo;
}

Immutability is sometimes preferred. One reason is that it helps with thread-safety.

Personally, I follow the rule, "if it can be final, it should be final."

Testing:

You won't need reflection to set the dependencies. Yes, many mocking frameworks handle this for you, but with constructor injection, you have the option to call new on the constructor.

Nasty NullPointerExceptions:

An object is created by calling its constructor, right? We usually want our arguments to be non-null at the time they are passed in. With constructor injection, the Spring IoC container makes sure that all the arguments passed in the constructor are available before passing them into the constructor.

CodePudding user response:

use constructor injection, Spring also recommends it

CodePudding user response:

In your main code, you should use method 2 as field injection (method 1) is not recommended. (see here for reasons)

In your test code, it's okay to use method 1.

CodePudding user response:

In addition to what the other answers have said about immutability, another benefit of constructor injection is to be able to avoid NPE is the field is not initialized. Using autowired, from a test, you’d create the class and then must remember to set the field. Using constructor injection, you can’t not initialize the field. This is more prominent in Kotlin where autowired fields are declared as lateinit var and throw a runtime exception if used before initialized. But a constructor argument can be declared as not null type which prevents you from even explicitly passing null.

  • Related