Spring Boot @Autowired Field Null - Why?

By Arvind Rai, September 25, 2023
On this page we will learn the common causes for null value of an @Autowired field in Spring Boot application. Spring injects the instance of only Spring managed bean to the autowired field of a class. Find the common causes for null value of an autowired field.
1. Creating object using new keyword.
2. Class is not annotated with stereotype annotations such as @Component.
3. Using @Autowired on static fields.
4. Fetching a field of Spring managed bean that is not annotated with @Autowired.
5. Fetching autowired field within constructor.
6. Not enabling @Autowired annotation in XML configuration for beans declared using XML.

Let us discuss the common causes for null value in detail.

1. Do not create object using new keyword

In Spring dependency injection, the object of the class should be obtained through dependency injection, for example using @Autowired annotation. Suppose a class Customer has a dependency of Address class and has resolved by @Autowired annotation.
@Component
public class Customer {
	@Autowired
	private Address address;
} 
Suppose we initialize Customer using new keyword as below.
Customer customer = new Customer(); 
In this case the object address will not be autowired and the value be null. This is because when we create object using new keyword in our code, it fails the dependency injection. To avoid the null value, get Customer object through dependency injection as below.
@Autowired
private Customer customer; 
If we are fetching Customer object in main() method, use ApplicationContext.
@SpringBootApplication
public class SpringBootAppStarter {
  public static void main(String[] args) throws Exception {
     ConfigurableApplicationContext ctx = SpringApplication.run(SpringBootAppStarter.class, args);
     Customer customer = ctx.getBean(Customer.class);
  }
} 

2. Class is not annotated with @Component

For dependency injection the class must be a Spring bean either by XML configuration or using @Component or other stereotype annotations such as @Service, @Repository and @Controller.
public class Address {
}
@Component
public class Customer {
	@Autowired
	private Address address;
} 
In the above code when we access address object, it will throw NullPointerException, this is because it is not autowired successfully. The Address class must also be a component.
@Component
public class Address {
} 

3. Autowired Field is Static

Spring does not support dependency injection on static fields. If we use @Autowired annotation on static fields, the value of these fields will be null.
Look into the below code snippet.
@Autowired
private static Address address; 
When we access address field, its value will be null.

4. Missing @Autowired on a Field

Look into the code below.
@Component
public class Address {
} 
The Address class is a component and is eligible to be autowired.
@Component
public class Customer {
	private Address address;

	public Address getAddress() {
		return address;
	}
} 
The field address has not been annotated with @Autowired and hence no injection will take place. When we access its value, it will be null.
@Service
public class CustomerService {
	@Autowired
	private Customer customer;
	
	public void displayData() {
		System.out.println(customer.getAddress().getCity());
	}
} 
displayData() method will through NullPointerException.
We can fix the error just by annotating address field with @Autowired.
@Component
public class Customer {
	@Autowired
	private Address address;
    ------
} 

5. Fetching Autowired Field in Constructor

If we fetch an autowired field of a class within the constructor of that class, we will face NullPointerException. Find the code below.
@Service
public class CustomerService {
	@Autowired
	private Customer customer;
	
	public CustomerService() {
		System.out.println(customer.getMessage());
	}
} 
The customer field is annotated with @Autowired. I am fetching this object within constructor and I will get null value. This is because we are fetching the field before dependency injection.

6. Not Enabling Annotation Configuration For XML Bean

To enable @Autowired annotation using XML configuration, use <context:annotation-config/>.
Find a class that is using autowired field.
public class CustomerService {
	@Autowired
	private Customer customer;
} 
Find the XML configuration to create CustomerService bean.
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd">
           
	<bean id="customerService" class="com.concretepage.CustomerService" />
</beans> 
We need to use <context:annotation-config/> to enable @Autowired otherwise we will get null value for customer field of CustomerService bean.
The <context:annotation-config/> enables @Required, @Autowired, @PostConstruct, @PreDestroy and @Resource etc.

Use <context:annotation-config/> in XML configuration as following.
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config />
	<bean id="customerService" class="com.concretepage.CustomerService" />
</beans> 

7. Reference

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us