Spring Annotations allow us to configure dependencies and implement dependency injection through java programs. Those are a form of metadata that provides data about a program. The @Required annotation in spring is a method-level annotation used in the setter method of a bean property and therefore making the setter-injection compulsory. This annotation suggests that the required bean property must be injected with a value at the configuration time which we will show and explain in the following example.
Prerequisites:
Implementation:
Step 1: First, let’s create a simple Spring Application and inject the literal values by setter injection. So, create a simple class Student having three attributes rollNo, name, and age. Create setter methods for these two attributes and a simple method to print the details of the student.
File: Student.java
Java
// Java Program to Illustrate Student Class // Class public class Student { // Class data members private int rollNo; private String name; private int age; // Setter public void setRollNo( int rollNo) { this .rollNo = rollNo; } // Setter public void setName(String name) { this .name = name; } // Setter public void setAge( int age) { this .age = age; } // Method public void display() { // Printing attributes of student System.out.println( "Roll No: " + rollNo); System.out.println( "Name: " + name); System.out.println( "Age: " + age); } } |
Step 2: Let’s create a properties file in your classpath and name the file as student-info.properties (for this example we name it like this, you can name it according to your need). And in this file, we are going to write something like this
student.rollNo = 201 student.name = Asish student.age = 30
Step 3: Let’s set the values from the properties file by using the @Value Annotation. So, we can modify our Student.java file something like this
Java
import org.springframework.beans.factory.annotation.Value; public class Student { private int rollNo; private String name; private int age; @Value ( "${student.rollNo}" ) public void setRollNo( int rollNo) { this .rollNo = rollNo; } @Value ( "${student.name}" ) public void setName(String name) { this .name = name; } @Value ( "${student.age}" ) public void setAge( int age) { this .age = age; } public void display(){ System.out.println( "Roll No: " + rollNo); System.out.println( "Name: " + name); System.out.println( "Age: " + age); } } |
Step 4: Now let’s create a Student Bean in the beans.xml file. Below is the complete code for the beans.xml file
XML
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://www.springframework.org/schema/beans < context:annotation-config /> < context:property-placeholder location = "classpath:student-info.properties" /> < bean id = "student" class = "Student" > </ bean > </ beans > |
Step 5: So now our bean is ready. Now let’s create a class and define the main() method inside that class. Suppose we have created a class named Main and we have defined the main() method inside this class. Below is the code for the Main.java class. Comments are added inside the code for better understanding.
A. File: Main.java
Java
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // Using ApplicationContext tom implement Spring IoC ApplicationContext context = new ClassPathXmlApplicationContext( "beans.xml" ); // Get the bean student Student student = context.getBean( "student" , Student. class ); // Calling the methods student.display(); } } |
Now run your main() method and the output will be like this.
Output:
Roll No: 201 Name: Asish Age: 30
So our application is working fine. Now let’s come again to the Student.java file and remove the @Value(“${student.rollNo}”) before the setRollNo() method. So now our modified Student.java file is something like this as follows:
B. File: Student.java
Java
import org.springframework.beans.factory.annotation.Value; public class Student { private int rollNo; private String name; private int age; public void setRollNo( int rollNo) { this .rollNo = rollNo; } @Value ( "${student.name}" ) public void setName(String name) { this .name = name; } @Value ( "${student.age}" ) public void setAge( int age) { this .age = age; } public void display(){ System.out.println( "Roll No: " + rollNo); System.out.println( "Name: " + name); System.out.println( "Age: " + age); } } |
Now again run your main() method and the output will be like this.
Output:
Roll No: 0 Name: Asish Age: 30
So the Student class object is created but the Roll no value has not been assigned. But we want the Roll No value must be filled before creating the Student class object. You can consider like Roll no is a primary key and we don’t want this value as null. So here @Required Annotation comes into the picture. So if we modify our Student.java file as the following them we are going to get exceptions in our program.
C. File: Student.java
Java
import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Value; public class Student { private int rollNo; private String name; private int age; @Required public void setRollNo( int rollNo) { this .rollNo = rollNo; } @Value ( "${student.name}" ) public void setName(String name) { this .name = name; } @Value ( "${student.age}" ) public void setAge( int age) { this .age = age; } public void display(){ System.out.println( "Roll No: " + rollNo); System.out.println( "Name: " + name); System.out.println( "Age: " + age); } } |
Exception:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'student' defined in class path resource [beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'rollNo' is required for bean 'student' at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:610) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85) at Main.main(Main.java:7) Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'rollNo' is required for bean 'student' at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:158) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1418) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ... 11 more
So in this scenario, the exception console is trying to tell us that it’s mandatory to provide the value to the Roll no to create the Student class object. So if you want some field value must be filled with some value then you should use the @Required Annotation. So we can modify our Student.java file something like this as follows:
D. File: Student.java
Java
// Java Program to Illustrate Modified Student Class // Importing required classes import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Value; // Class public class Student { // Class data members private int rollNo; private String name; private int age; // Annotation @Required @Value ( "${student.rollNo}" ) // Setter public void setRollNo( int rollNo) { this .rollNo = rollNo; } // Setter @Value ( "${student.name}" ) public void setName(String name) { // this keyword refers to current instance itself this .name = name; } // Setter @Value ( "${student.age}" ) public void setAge( int age) { this .age = age; } // Method public void display() { // Display message only System.out.println( "Roll No: " + rollNo); System.out.println( "Name: " + name); System.out.println( "Age: " + age); } } |
Return the program again and you are going to get the output as below as shown:
Output:
Roll No: 0 Name: Asish Age: 30