javadependency-injectioninversion-of-controlautowired

Which approach is more efficent @Autowired or private final?


My question is simple. Which approach is more efficient? As I see, the DI in the method2 is more recent. But I wanted to ask you which one should I use?

method 1:

@Autowired
private CustomerRepository customerRepo;

method 2:

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

Solution

  • TL;DR: Method 2 is much more flexible.

    Method 1 is an example of field injection and method 2 is an example of constructor 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. Another is security.

    Personally, I follow the rule, "if it can be final, it should be final." EDIT 23-05-23: This rule doesn't make sense if you are writing a library, since you want functionality to be easily extended and changed.

    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.