@Required annotation is placed in Spring API package org.springframework.beans.factory.annotation.* . This annotation is used for checking Spring Dependency. It checks whether properties of bean are set or not. @Required annotation is placed over the setter for the properties which is to be checked for Spring Dependency.
A Spring Bean by the name "RequiredAnnotationBeanPostProcessor" checks if properties annotated with @Required have been set. Before a bean is initialized into a Spring Container this bean post processor checks for properties whether are set or not (marked as @Required).
Let's look at it by a simple example -
(WITHOUT @Required ANNOTATION)
1. Create a class say "Address.java"
2. Create a class say "Employee.java"
3. Create a Spring Configuration file say "spring.xml"
4. Create a Test class say "Test.java"
As we haven't provided Dependency Injection for Address bean in Employee bean. When we run the above Test class the output comes out to be as -
Exception in thread "main" FirstName : Dinesh
java.lang.NullPointerException
at com.hubberspot.spring.ioc.Test.main(Test.java:36)
Its a null pointer exception because Address bean is not set in Employee bean. When we access the properties of Address bean through Address we get null pointer exception.
(WITH @Required ANNOTATION)
1. Create a class say "Address.java"
2. Create a class say "Employee.java" having @Required annotation on Address setter method.
3. Create a Spring Configuration file say "spring.xml" having a tag context:annotation-config for registering RequiredAnnotationBeanPostProcessor which checks if all the bean properties with the @Required annotation have been set.
4. Create a Test class say "Test.java"
As we haven't provided Dependency Injection for Address bean in Employee bean but this time we have marked setter method of Address with @Required annotation. When we run the above Test class the output comes out to be as -
Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'employee' defined in class path resource [spring.xml]:
Initialization of bean failed; nested exception is
org.springframework.beans.factory.BeanInitializationException:
Property 'address' is required for bean 'employee'
It checks this time before initialization of Employee bean that Address bean is not injected and exception is thrown.
A Spring Bean by the name "RequiredAnnotationBeanPostProcessor" checks if properties annotated with @Required have been set. Before a bean is initialized into a Spring Container this bean post processor checks for properties whether are set or not (marked as @Required).
Let's look at it by a simple example -
(WITHOUT @Required ANNOTATION)
1. Create a class say "Address.java"
package com.hubberspot.spring.ioc;
public class Address {
private String street;
private String city;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
2. Create a class say "Employee.java"
package com.hubberspot.spring.ioc;
public class Employee {
private String firstName;
private Address address;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
3. Create a Spring Configuration file say "spring.xml"
<beans xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemalocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="com.hubberspot.spring.ioc.Employee" id="employee">
<property name="firstName" value="Dinesh"></property>
</bean>
<bean class="com.hubberspot.spring.ioc.Address" id="address">
<property name="street" value="Park Street"></property>
<property name="city" value="Pune"></property>
</bean>
</beans>
4. Create a Test class say "Test.java"
package com.hubberspot.spring.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// ApplicationContext is a Spring interface which
// provides with the configuration for an application.
// It provides us with all the methods that BeanFactory
// provides. It loads the file resources in a older
// and generic manner. It helps us to publish events to the
// listener registered to it. It also provides quick support
// for internationalization. It provides us with the object
// requested, it reads the configuration file and provides
// us with the necessary object required.
// We are using concrete implementation of ApplicationContext
// here called as ClassPathXmlApplicationContext because this
// bean factory reads the xml file placed in the classpath of
// our application. We provide ClassPathXmlApplicationContext
// with a configuration file called as spring.xml placed
// at classpath of our application.
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// In order to get a object instantiated for a particular bean
// we call getBean() method of ClassPathXmlApplicationContext
// passing it the id for which the object is to be needed.
// Here getBean() returns an Object. We need to cast it back
// to the Employee object. Without implementing new keyword we
// have injected object of Employee just by reading an xml
// configuration file.
Employee employee = (Employee) context.getBean("employee");
System.out.println("FirstName : " + employee.getFirstName());
System.out.println("Address : " + employee.getAddress().getStreet() + " , "
+ employee.getAddress().getCity());
}
}
As we haven't provided Dependency Injection for Address bean in Employee bean. When we run the above Test class the output comes out to be as -
Exception in thread "main" FirstName : Dinesh
java.lang.NullPointerException
at com.hubberspot.spring.ioc.Test.main(Test.java:36)
Its a null pointer exception because Address bean is not set in Employee bean. When we access the properties of Address bean through Address we get null pointer exception.
(WITH @Required ANNOTATION)
1. Create a class say "Address.java"
package com.hubberspot.spring.ioc;
public class Address {
private String street;
private String city;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
2. Create a class say "Employee.java" having @Required annotation on Address setter method.
package com.hubberspot.spring.ioc;
import org.springframework.beans.factory.annotation.Required;
public class Employee {
private String firstName;
private Address address;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Address getAddress() {
return address;
}
@Required
public void setAddress(Address address) {
this.address = address;
}
}
3. Create a Spring Configuration file say "spring.xml" having a tag context:annotation-config for registering RequiredAnnotationBeanPostProcessor which checks if all the bean properties with the @Required annotation have been set.
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<bean id="employee" class="com.hubberspot.spring.ioc.Employee">
<property name="firstName" value="Dinesh"></property>
</bean>
<bean id="address" class="com.hubberspot.spring.ioc.Address">
<property name="street" value="Park Street"></property>
<property name="city" value="Pune"></property>
</bean>
</beans>
4. Create a Test class say "Test.java"
package com.hubberspot.spring.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// ApplicationContext is a Spring interface which
// provides with the configuration for an application.
// It provides us with all the methods that BeanFactory
// provides. It loads the file resources in a older
// and generic manner. It helps us to publish events to the
// listener registered to it. It also provides quick support
// for internationalization. It provides us with the object
// requested, it reads the configuration file and provides
// us with the necessary object required.
// We are using concrete implementation of ApplicationContext
// here called as ClassPathXmlApplicationContext because this
// bean factory reads the xml file placed in the classpath of
// our application. We provide ClassPathXmlApplicationContext
// with a configuration file called as spring.xml placed
// at classpath of our application.
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// In order to get a object instantiated for a particular bean
// we call getBean() method of ClassPathXmlApplicationContext
// passing it the id for which the object is to be needed.
// Here getBean() returns an Object. We need to cast it back
// to the Employee object. Without implementing new keyword we
// have injected object of Employee just by reading an xml
// configuration file.
Employee employee = (Employee) context.getBean("employee");
System.out.println("FirstName : " + employee.getFirstName());
System.out.println("Address : " + employee.getAddress().getStreet() + " , "
+ employee.getAddress().getCity());
}
}
As we haven't provided Dependency Injection for Address bean in Employee bean but this time we have marked setter method of Address with @Required annotation. When we run the above Test class the output comes out to be as -
Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'employee' defined in class path resource [spring.xml]:
Initialization of bean failed; nested exception is
org.springframework.beans.factory.BeanInitializationException:
Property 'address' is required for bean 'employee'
It checks this time before initialization of Employee bean that Address bean is not injected and exception is thrown.