Master Spring & Java Development!
Subscribe to Ram N Java for clean, beginner-friendly coding guides!
🔔 Subscribe to Ram N JavaOverview: Spring Dependency Checking with @Required
When configuring beans in the Spring Framework, missing configuration properties can cause severe runtime bugs such as unexpected NullPointerException failures. To guarantee that all required bean dependencies and properties are properly populated at configuration time, Spring provides dependency checking capabilities powered by the @Required annotation.
In this guide, you will understand how dependency checking works with the @Required annotation, how Spring detects missing properties at container startup, and how to apply this to build robust Java enterprise applications.
Key Concepts of Dependency Checking
The @Required annotation enforces strict dependency contracts on bean properties:
- Enforcing Setter Injection: Placed directly on setter methods, it mandates that the associated property must be explicitly defined in XML configuration files or through automated property definitions.
-
Early Failure Detection (Fail-Fast): Instead of failing when the bean is actually used during application execution, Spring halts during initialization by throwing a
BeanInitializationExceptionif the property was omitted. -
Post-Processor Verification: Handled by
RequiredAnnotationBeanPostProcessor, which inspects the bean properties right after instantiation and property setting. - Improved Code Reliability: Prevents uninitialized dependencies from escaping into business logic, leading to cleaner and more maintainable codebases.
Step-by-Step Configuration
-
Annotate Setter Methods: Mark the required setter method with
@Required:
@Required
public void setStudentName(String studentName) {
this.studentName = studentName;
} -
Register RequiredAnnotationBeanPostProcessor: Enable annotation support in XML via
<context:annotation-config />or explicitly register the bean post-processor:
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> -
Configure the Bean Property: Provide the
<property>tag in your bean definition. If left out, Spring throws an exception on startup alerting you to the missing dependency.
Recommended Next Videos from Ram N Java
Click here to watch on Youtube:
https://www.youtube.com/watch?v=Mu8-swqQTDs&index=1&list=UUhwKlOVR041tngjerWxVccw
Click the below Image to Enlarge:
| Spring dependency checking with @Required Annotation V1 | Spring Tutorial |
| Spring dependency checking with @Required Annotation V1 | Spring Tutorial |
| Spring dependency checking with @Required Annotation V1 | Spring Tutorial |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0%20http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ram.core</groupId>
<artifactId>SpringDemo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringDemo</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
Address.java
public class Address
{
private String city;
private String state;
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
public String getState()
{
return state;
}
public void setState(String state)
{
this.state = state;
}
@Override
public String toString()
{
return "Address [city=" + city + ", state=" + state + "]";
}
}
Employee.java
import org.springframework.beans.factory.annotation.Required;
public class Employee
{
private int id;
private String name;
private Address address;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Address getAddress()
{
return address;
}
@Required
public void setAddress(Address address)
{
this.address = address;
}
@Override
public String toString()
{
return "Employee [id=" + id + ", name=" + name + ", address=" + address
+ "]";
}
}
applicationContext.xml
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-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="address" class="com.ram.model.Address">
<property name="city" value="TamilNadu"></property>
<property name="state" value="Chennai"></property>
</bean>
<bean id="employee" class="com.ram.model.Employee">
<property name="id" value="100"></property>
<property name="name" value="Peter"></property>
<!-- <property name="address" ref="address"></property> -->
</bean>
<context:annotation-config />
</beans>
App.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ram.model.Employee;
public class App
{
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("---------------------------------------");
Employee employee = context.getBean("employee", Employee.class);
System.out.println(
"Got employee object from the ApplicationContext(Spring Container)");
System.out.println(employee);
}
}
Output
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sat Aug 04 10:34:25 IST 2018]; root of context hierarchy
Aug 04, 2018 10:34:25 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
Aug 04, 2018 10:34:26 AM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:758)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
at com.ram.core.App.main(App.java:12)
Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:156)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
... 11 more
Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Required_Annotation.zip?attredirects=0&d=1
Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Required_Annotation
Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/eb94a9e0ae07f3c6a86034ef414051430bbfc9bc/Spring_2018/SpringDemo_Required_Annotation/?at=master
See also:
No comments:
Post a Comment