Spring Custom @Required styled annotation Example

In this tutorial we are creating and configuring our own custom spring @Required annotation type. This is as simple as creating the annotation, enabling the required bean dependency checking and registering the custom annotation with spring. Let’s see how.

Spring Custom @Required styled Annotation

First, create a custom @WeNeedThis annotation. We are using this annotation as a replacement for the @Required annotation. We need the same annotation signature as the original annotation. We cannot change the @Target configuration to ElementType.FIELD for example.

package com.memorynotfound.spring.core.required;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface WeNeedThis {
}

Using the custom @Required annotation

We annotate our setter method with the @WeNeedThis method. At the moment this annotation doesn’t do anything. We need to register this annotation as a @Required styled annotation with the spring container.

package com.memorynotfound.spring.core.required;

public class StarWars {

    private TheForce theForce;

    public TheForce getTheForce() {
        return theForce;
    }

    @WeNeedThis
    public void setTheForce(TheForce theForce) {
        this.theForce = theForce;
    }
}

This object is required in the StarWars class.

package com.memorynotfound.spring.core.required;

public class TheForce {

}

Registering the custom @Required annotation

The RequiredAnnotationBeanPostProcessor is a spring bean post processor that is responsible for checking if all the bean properties with the @Required annotations have been configured correctly. In other words, without the RequiredAnnotationBeanPostProcessor the required annotation will not work. We can configure a custom required annotation by setting the requiredAnnotationType with the fully qualified class name of our custom annotation.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
        <property name="requiredAnnotationType" value="com.memorynotfound.spring.core.required.WeNeedThis"/>
    </bean>

    <bean id="theForce" class="com.memorynotfound.spring.core.required.TheForce"/>
    <bean id="c3po" class="com.memorynotfound.spring.core.required.StarWars">
        <property name="theForce" ref="theForce"/>
    </bean>

    <bean id="luke" class="com.memorynotfound.spring.core.required.StarWars"/>

</beans>

Bootstrapping the application

We did not initialize all the classes with the custom @WeNeedThis annotation, so the application will fail at startup.

package com.memorynotfound.spring.core.required;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String... args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");
        StarWars starWars = (StarWars)context.getBean("luke");
        System.out.println(starWars);

        starWars = (StarWars)context.getBean("c3po");
        System.out.println(starWars);
    }
}

Because we didn’t initialize all the required properties, we receive the following exception.

Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'theForce' is required for bean 'luke'
	at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:156)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
	... 11 more

References

Download

You may also like...