Spring @Required Annotation Example
March 12, 2023
This page will walk through Spring @Required
annotation example using XML and JavaConfig. The @Required
annotation makes a setter method mandatory to be injected by Spring container. Application throughs error, if we will not provide dependency injection to these methods. Spring provides RequiredAnnotationBeanPostProcessor
class which is used to fulfill dependency injection for required properties of bean. Spring has default implementation of this class and we can also use it for custom requirement. To use @Required
annotation, we need to create bean for RequiredAnnotationBeanPostProcessor
in our Spring application context XML file. If we are using context:annotation-config
or context:component-scan
element or @ComponentScan
annotation, we need not to create bean for RequiredAnnotationBeanPostProcessor
because they have already default implementation of it.
In case we are using
@Autowired
annotation on our setter method, we need not to use @Required
annotation because by default @Autowired
annotation has true value for its required
attribute.
Note: As of Spring 5.1, the
@Required
annotation is deprecated in favor of using constructor injection for required settings.
Contents
@Required Annotation with RequiredAnnotationBeanPostProcessor using XML
RequiredAnnotationBeanPostProcessor
ensures for setting bean properties. A class property is annotated with @Required
to make compulsory to set value while defining bean. If required bean properties are not set, spring throws error. For this RequiredAnnotationBeanPostProcessor
should be configured in spring application context XML. In this way, we will be sure of dependency injection for some of our required properties in bean definition in our application. In case we are using context:annotation-config
and context:component-scan
tag in our application context XML, a default RequiredAnnotationBeanPostProcessor
is already registered with it and we need not to create bean for RequiredAnnotationBeanPostProcessor
.
app-conf-1.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> <bean id="address" class="com.concretepage.Address"> <property name="city" value="Varanasi"/> </bean> </beans>
package com.concretepage; import org.springframework.beans.factory.annotation.Required; public class Address { private String village; private String city; public String getVillage() { return village; } public void setVillage(String village) { this.village = village; } public String getCity() { return city; } @Required public void setCity(String city) { this.city = city; } }
package com.concretepage; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringDemo { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-conf-1.xml"); Address add = (Address)context.getBean("address"); System.out.println(add.getCity()); context.registerShutdownHook(); } }
20:52:55.539 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'address' Varanasi 20:52:55.554 [Thread-0] INFO o.s.c.s.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@6073f712: startup date [Thu Jan 07 20:52:54 IST 2016]; root of context hierarchy
app-conf-1.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> <bean id="address" class="com.concretepage.Address"> </bean> </beans>
Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'city' is required for bean 'address' at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:156)
@Required Annotation with context:annotation-config Tag using XML
context:annotation-config
enables annotations for example @Required
and @Autowired
etc which are used at class property label. A default RequiredAnnotationBeanPostProcessor
is registered with context:annotation-config
tag. In case we are using context:annotation-config
tag in our application context XML, we need not to create bean for RequiredAnnotationBeanPostProcessor
.
app-conf-2.xml
<?xml version="1.0" encoding="UTF-8"?> <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="address" class="com.concretepage.Address"> <property name="city" value="Varanasi"/> </bean> </beans>
@Required Annotation with context:component-scan Tag using XML
In spring application context XML,context:component-scan
is a tag using which we will be able to scan the java classes annotated with @Component
, @Repository
, @Service
, and @Controller
stereotypes and will be behaved as spring bean. We need to define package name to scan using the attribute base-package
. To enable annotations such as @Required
and @Autowired
etc which are used at class property label, context:component-scan
has an attribute annotation-config
that can have true or false value. If we are using context:component-scan
tag with annotation-config
as true, then we need not to create bean for RequiredAnnotationBeanPostProcessor
. The default value of annotation-config
attribute is true.
app-conf-3.xml
<?xml version="1.0" encoding="UTF-8"?> <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:component-scan base-package="com.concretepage" annotation-config="true"/> <bean id="address" class="com.concretepage.Address"> <property name="city" value="Varanasi"/> </bean> </beans>
@Required Annotation using JavaConfig
For the demo of@Required
annotation with JavaConfig, we are creating two classes College
and Person
. The setter method of Person
class has been marked with @Required
annotation. In this case we must have to inject its dependency otherwise spring container will through error. In our JavaConfig class we are creating beans for these classes and at the same time we are injecting the dependency.
Person.java
package com.concretepage; import org.springframework.beans.factory.annotation.Required; public class Person { private College college; public College getCollege() { return college; } @Required public void setCollege(College college) { this.college = college; } }
package com.concretepage; public class College { private String name; private String location; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public College college() { College college = new College(); college.setName("SSIC"); college.setLocation("Jaunpur"); return college; } @Bean public Person person(College college) { Person person = new Person(); person.setCollege(college); return person; } }
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class SpringDemo { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); Person person = ctx.getBean(Person.class); System.out.println(person.getCollege().getName()); ctx.registerShutdownHook(); } }
Now I am done. Happy spring learning!