Spring Field Injection Example and It's Drawbacks

Apart from constructor based and setter based dependency injection. There is a third type of dependency injection supported in Spring called field injection. As the name says, the dependency is injected directly in the field, with no constructor or setter needed. This is done by annotating the class member with the @Autowired annotation.
Let's first demonstrates the usage of field injection with an example and then we will explore its drawbacks.

1. Spring Field Injection Example

FieldBasedInjection.java

In the following code snippet, the bean of type FieldBasedInjection has a field of type MessageService:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.javadevsguide.springframework.di.service.MessageService;

@Component
public class FieldBasedInjection {

    @Autowired
    @Qualifier("TwitterService")
    private MessageService messageService;

    public void processMsg(String message) {
        messageService.sendMsg(message);
    }
}
The field is private, but the Spring IoC container does not really care about that; it uses reflection to populate the required dependency.

MessageService

Here is the MessageService interface and it's implementation class code:
package com.javadevsguide.springframework.di.service;

public interface MessageService {
 public void sendMsg(String message);

TwitterService.java

package com.javadevsguide.springframework.di.service;

import org.springframework.stereotype.Service;

@Service("TwitterService")
public class TwitterService implements MessageService {

    public void sendMsg(String message) {
        System.out.println(message);
    }
}

Spring Java Configuration - AppConfiguration.java

Let's create a spring configuration file using java class AppConfiguration and annotated with @Configuration annotation. This is equivalent to the spring XML configuration file without beans definition.
package com.javadevsguide.springframework.di.config;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.javadevsguide.springframework.di")
public class AppConfiguration {

}

Test Application with ApplicationContext

package com.javadevsguide.springframework.di.test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.javadevsguide.springframework.di.config.AppConfiguration;
import com.javadevsguide.springframework.di.field.FieldBasedInjection;

public class TestApplication {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
        FieldBasedInjection fieldBasedInjection = applicationContext.getBean(FieldBasedInjection.class);
        fieldBasedInjection.processMsg("twitter message sending ");
    }
}
Output:
twitter message sending 

2. Field Injection Drawbacks

There are drawbacks, and this is why using field injection is usually avoided.
  • Although it is easy to add dependencies this way, we must be careful not to violate the single responsibility principle. Having more dependencies means more responsibilities for a class, which might lead to the difficulty of separating concerns at refactoring time. The situation when a class becomes bloated is easier to see when dependencies are set using constructors or setters but is quite well hidden when using field injection.
  • The responsibility of injecting dependencies is passed to the container in Spring, but the class should clearly communicate the type of dependencies needed using a public interface, through methods or constructors. Using field injections, it can become unclear what type of dependency is really needed and if the dependency is mandatory or not.
  • Field injection introduces a dependency of the Spring container, as the @Autowired annotation is a Spring component; thus, the bean is no longer a POJO and cannot be instantiated independently.
  • Field injection cannot be used for final fields. This type of field can only be initialized using constructor injection.
  • Field injection introduces difficulties when writing tests as the dependencies have to be injected manually.

3. Conclusion

In this article, we have discussed spring field injection with an example. We have explored the drawbacks of using spring field injection, and this is why using field injection is usually avoided.
The source code of this article available on my GitHub repository at https://github.com/RameshMF/spring-core-tutorial/tree/master/spring-dependency-injection

4. Related Posts

Guide to Dependency Injection in Spring - This guide provides what is dependency injection in Spring framework and what are different types of dependency injection supports in Spring with examples (constructor and setter method).

Spring Dependency Injection via Setter Example - In this article, we will learn how to use setter-based dependency injection in Spring Applications.

 Spring Dependency Injection via Constructor Example - In this article, we will learn how to use constructor-based dependency injection in Spring Applications.

Spring - @DependsOn Annotation Example - In this article, we will discuss how to use @DependsOn annotation in Spring Applications with an example. 

Comments