February 19, 2022

Spring @Required Annotation

Spring @Required annotation is used with a method, typically a setter method thus making setter dependency injection for that property mandatory.

RequiredAnnotationBeanPostProcessor class

Registering RequiredAnnotationBeanPostProcessor class is required to use @Required annotation. A default RequiredAnnotationBeanPostProcessor will be registered by the "context:annotation-config" and "context:component-scan" XML tags.

Spring @Required annotation examples

In the example there are two classes Person and Address.

Address.java

public class Address {

  private String houseNo;
  private String street;
  private String city;
  private String state;
  private String pinCode;

  public String getHouseNo() {
    return houseNo;
  }
  public String getStreet() {
    return street;
  }
  public String getCity() {
    return city;
  }
  public String getState() {
    return state;
  }
  public String getPinCode() {
    return pinCode;
  }
  public void setHouseNo(String houseNo) {
    this.houseNo = houseNo;
  }
  public void setStreet(String street) {
    this.street = street;
  }
  public void setCity(String city) {
    this.city = city;
  }
  public void setState(String state) {
    this.state = state;
  }
  public void setPinCode(String pinCode) {
    this.pinCode = pinCode;
  }
}
Person.java
public class Person {

  private String name;
  private int age;
  private Address address;

  public String getName() {
    return name;
  }
  @Required
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  @Required
  public void setAddress(Address address) {
    this.address = address;
  }
  public Address getAddress() {
    return address;
  }
}

In the Person class field name and address reference are annotated with @Required annotation. That means these values are required otherwise BeanCreationException is thrown.

XML Configuration
<?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.xsd   
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
  <!-- Takes care of registering RequiredAnnotationBeanPostProcessor  -->
  <context:annotation-config/>

  <bean id="person" class="com.knpcode.springexample.Person">
    <!-- <property name="name" value="John"></property> -->  
    <property name="age" value="35"></property> 
  </bean>
    
  <bean id="address" class="com.knpcode.springexample.Address">
    <property name="houseNo" value = "432" />
    <property name="street" value = "E Lafayette Street" />
    <property name="city" value = "Detroit" />
    <property name="state" value = "Michigan" />
    <property name="pinCode" value = "48207" />
  </bean>
</beans>

Here note that name property is not provided so as the address reference though both fields are annotated with @Required annotation.

Now if you run this example-

public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");
    Person person = context.getBean("person", Person.class);
    System.out.println("City- " + person.getAddress().getCity());

    context.close();
  }
}
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean 
with name 'person' defined in class path resource [appcontext.xml]: 
Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Properties 'address' and 'name' are required for bean 'person'

As you can see Spring container failed to create the bean "person" because oroperties 'address' and 'name' are required and value for those properties is not provided.

Making changes in the XML configuration to include required properties.

<?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.xsd   
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
  <!-- Takes care of registering RequiredAnnotationBeanPostProcessor  -->
  <context:annotation-config/>

  <bean id="person" class="com.knpcode.springexample.Person">
    <property name="name" value="John"></property>
    <property name="age" value="35"></property> 
    <property name="address" ref="address" />
  </bean>
    
  <bean id="address" class="com.knpcode.springexample.Address">
    <property name="houseNo" value = "432" />
    <property name="street" value = "E Lafayette Street" />
    <property name="city" value = "Detroit" />
    <property name="state" value = "Michigan" />
    <property name="pinCode" value = "48207" />
  </bean>
</beans>

Now the proper output is displayed-

City- Detroit

Note that Spring @Required annotation is deprecated as of 5.1, in favor of using constructor injection for required settings.

That's all for the topic Spring @Required Annotation. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment