Using Spring & Java Annotations to Inject Reusable Capabilities

January 19, 2011

Want to inject reusable functionality but don’t want your consumers to go through complex set of steps to implement? Using annotations, a reusable capability can be injected at runtime – your clients can take advantage of common, reusable capabilities while avoiding the need to implement boiler plate code. Consumers can also be allowed to declaratively specify/alter the reusable asset’s behavior using this approach.

Here is an example using Java and Spring framework to print a test message before invoking the target method.

Declare an annotation – a simple annotation with a boolean flag:

package example.annotation;

import java.lang.annotation.*;

public @interface Loggable {
	 boolean log() default true;

Create a dynamic proxy – all this does is examines the boolean log method from the annotation and prints a test message:

package example.proxy;

import java.lang.reflect.*;
import example.annotation.Loggable;

public class ExampleDynamicProxy implements InvocationHandler {

	private Loggable loggable = null;
	private final Object targetObject;

	public ExampleDynamicProxy(Object target, Loggable loggable) {
		targetObject = target;
		this.loggable = loggable;

	public Object invoke(Object target, Method method, Object[] arguments) throws Throwable {

		Object result = null;
		try {
			if (loggable.log()) {
			  System.out.println("message before invoking method...");
			result = method.invoke(targetObject, arguments);
		} catch (InvocationTargetException ite) {
			throw ite.getTargetException();
		return result;

Create a spring bean post-processor – checks for annotation and creates a proxied version of bean:

package example.postprocessor;

import java.lang.reflect.Proxy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import example.annotation.Loggable;
import example.proxy.ExampleDynamicProxy;

public class ExampleBeanPostProcessor implements BeanPostProcessor {

	public Object postProcessBeforeInitialization(Object arg0, String arg1)
			throws BeansException {
		return arg0;

	public Object postProcessAfterInitialization(Object arg0, String arg1)
			throws BeansException {

		Class clz = arg0.getClass();
		Class[] interfaces = clz.getInterfaces();

		if (interfaces != null && interfaces.length == 1
                        && _interfaces[0].isAnnotationPresent(Loggable.class)) {

			Class _interface = interfaces[0];
			ClassLoader cl = arg0.getClass().getClassLoader();
			Loggable loggable = (Loggable)_interface.getAnnotation(Loggable.class);
			Object proxy= Proxy.newProxyInstance(cl, new Class[] {_interface}, new ExampleDynamicProxy(arg0,loggable));

                        return proxy;
		return arg0;

Annotate an example interface as Loggable – this model can be used to inject lot of other reusable capabilities (error handling, notifications to JMS destinations, or even perform data transformations):

package example.bean;

import example.annotation.Loggable;

public interface Example {
	public String getGreeting();

Finally, each consuming interface will have an implementation and has to be defined as a bean along with the post-processor during spring initialization. This is a trivial example but was meant to illustrate the injection of reusable behavior via java annotations.

%d bloggers like this: