



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.





@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 -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 -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.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 -It checks this time before initialization of Employee bean that Address bean is not injected and exception is thrown.