Since Spring 2.5, annotation-based configuration has been an alternative to XML setups. Annotation based configuration rely on the bytecode metadata for wiring up components instead of angle-bracket declarations (Also Read : Introduction to Spring Boot). Annotations can be used on the relevant class, method, or field declaration. In this tutorial I am going to explain about one of the spring annotation @Required with simple example.
Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches. In order to use annotation-based wiring, we need to enable it in our Spring configuration file. So we need to implicitly register annotations by including the following tag in an XML-based Spring 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"> <i> <context:annotation-config/></i> </beans>
Note: The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, RequiredAnnotationBeanPostProcessor (which I had mentioned in my previous post: Write your Extension Endpoints for Spring IOC Container).
Some of the important annotations are listed as below:
- @Required: Introduced in Spring 2.0, the @Required annotation applies to bean property setter methods.
- @Autowired: Introduced in Spring 2.5, the @Autowired annotation can apply to bean property setter methods, non-setter methods, constructor and properties.
- @Qualifier: The @Qualifier annotation along with @Autowired can be used to remove the confusion by specifiying which exact bean will be wired.
- JSR-250 Annotations: Introduced in Spring 2.5, it added support for JSR-250 based annotations which include @Resource, @PostConstruct and @PreDestroy annotations.
- JSR-330 Annotations: Introduced in Spring 3.0, it added support for JSR-330 based annotations contained in the javax.inject package such as @Inject and @Named.
In this post I shall cover @Required annotation. Rest of the annotations shall be covered in my next posts.
@Required Annotation
As said above the @Required annotation applies to bean property setter methods and enforces required properties. Let’s see this in an example below. Before we look into the example let’s see RequiredAnnotationBeanPostProcessor enabling. @Required annotation can be registered by enabling RequiredAnnotationBeanPostProcessor in two ways:
1. Include in bean configuration file.Example:
<?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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <b> <context:annotation-config/></b> <!-- Definition for Product bean --> <bean id="product" class="com.javabeat.requiredexample.Product"> <property name="name" value="ProductA" /> <!-- try without passing price and check the result --> <!-- property name="price" value="400"--/> </bean> </beans>
2. Include RequiredAnnotationBeanPostProcessor directly in bean configuration file.Example:
<?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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> <!-- Definition for Product bean --> <bean id="product" class="com.javabeat.requiredexample.Product"> <property name="name" value="ProductA" /> <!-- try without passing price and check the result --> <!-- property name="price" value="400"--/> </bean> </beans>
@Required Annotation Example
Let us have working Eclipse IDE in place and follow the following steps to create a Spring application:
- Create a project: Create a project with a name SpringAnnotationExamples and create a package com.javabeat.requiredexample under the src directory in the created project.
- Add Libraries: Add required Spring libraries using Add External JARs option as explained in the article Customizing callback methods.
- Create source files: Create Java classes Product and MainApp under the com.javabeat.requiredexample package.
- Create configuration file: Create XML based configuration file BeansRequirednnotation.xml under src directory.
Contents of Product.java are:
package com.javabeat.requiredexample; import org.springframework.beans.factory.annotation.Required; public class Product { private Integer price; private String name; public Integer getPrice() { return price; } @Required public void setPrice(Integer price) { this.price = price; } public String getName() { return name; } @Required public void setName(String name) { this.name = name; } }
Contents of MainApp are:
package com.javabeat.requiredexample; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "BeansRequirednnotation.xml"); Product product = (Product) context.getBean("product"); System.out.println("Product Name : " + product.getName()); System.out.println("Price : " + product.getPrice()); } }
Contents of BeansRequirednnotation.xml are:
<?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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:annotation-config/> <!-- Definition for Product bean --> <bean id="product" class="com.javabeat.requiredexample.Product"> <property name="name" value="ProductA" /> <!-- try without passing price and check the result --> <!-- property name="price" value="400"--/> </bean> </beans>
Here I’ve used this for enabling the annotation. Here I’ve commented the “price” property.
Execute the code
The final step is run the application. Once all the above code is ready execute and the below output appears on the console:
BeanInitializationException: Property 'price' is required for bean 'product'
Try the above example by removing the comment from the BeansRequirednnotation.xml file as show below:
<?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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:annotation-config/> <!-- Definition for Product bean --> <bean id="product" class="com.javabeat.requiredexample.Product"> <property name="name" value="ProductA" /> <!-- try with passing price and check the result --> <property name="price" value="400"/> </bean> </beans>
Now execute the code and the below output appears on the console:
Product Name : ProductA Price : 400
Summary
In this article I highlighted the concept of Annotation based Spring container configurations. We saw an example using @Required attribute and its functioning. In the next article I shall cover the functionality of @Autowired annotations. If you are interested in receiving the future articles, please subscribe here.
If you have any questions, please drop it in the comments section.