@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.