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.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
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 {

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

	@Override
	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;

@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.

Advertisements

Leverage the Service Refactoring Pattern

September 6, 2010

The Service Refactoring pattern facilitates changes in service logic and/or underlying service implementation while preserving existing consumer contracts.

The Service Refactoring pattern allows the service provider to change the service implementation while preserving existing service contracts. This allows the provider the flexibility to honor existing consumers while taking advantage of streamlined service logic and/or better technologies. If this idea sounds familiar, it is based on the refactoring principles and techniques advocated by Martin Fowler in the object oriented design paradigm and aims to achieve the same result for services in a SOA context. This pattern requires the development of an adapter – that will translate messages conforming to the existing contract into the refactored contract and vice versa.

This pattern:

  • Allows for phased migration of consumers who use existing contract to a new one
  • Allows the provider to upgrade/enhance service behavior in phases. The refactoring can be accomplished via multiple steps and don’t all have to be bundled in a single release
  • Eliminates the need for consumers to change code to take advantage of refactored service
  • Allows new consumers to bind to the enhanced service contract and allows for new and existing consumers to co-exist
  • Potentially enhance performance, availability, and scalability as new consumers come on board

There is a need for strong and coordinated service governance to make sure that consumers are aware of the refactoring effort, retest to validate the behavior, and ultimately provide sign-off for the service capability to be turned on in a production environment. At a minimum, this pattern needs to make sure that existing consumers conduct regression testing to guarantee that the refactored service doesn’t necessitate code changes.


Using Spring Interceptors to Reuse Functionality

August 29, 2010

Spring MVC interceptors (learn more about interceptor design pattern here) can be used to plug in functionality that needs to be executed as part of handling a request. These interceptors can be an ideal place to reuse functionality that is applicable for non-web application related scenarios. Interceptors can be used to execute horizontal, cross cutting concerns – e.g. security, metrics, logging, etc. If you have an existing component that was developed for a command-line application or a JMS event handler and need to reuse it in a web app, an interceptor would be an ideal choice.

Here is an example implementation for a a Spring Interceptor extending the HandlerInterceptorAdapter:

package com.yourapp.learn;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LoginInterceptor extends HandlerInterceptorAdapter {

 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
 Object handler) throws Exception {

 Boolean userAuthenticated = (Boolean)request.getSession().getAttribute("userAuthenticated");

 if (userAuthenticated) {
    return true;
 } else {
    return false;
 }

 }
}

This interceptor simply checks to see if the user is authenticated by looking for a session attribute. If the result is true, the request is processed further.
Here is an example bean definition fragment for utilizing the above:

<bean id="testInterceptor" />

<bean id="testSimpleUrlHandlerMapping"
 class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="interceptors">
 <list>
 <ref bean="testInterceptor"/>
 </list>
</property>

 <property name="mappings">
 <props>
 <prop key="/test">someController</prop>
 </props>
 </property>
</bean>

The actual logic can be in another component that is leveraged in the interceptor. The component itself could be reused across several apps. If such a component isn’t available, you can refactor existing logic to carve out the common functionality.


The Template Method Design Pattern

November 16, 2009

The template method design pattern defines a generic algorithm and specify hooks for plugging in extension points and variations. How does this fit in with systematic reuse? It supports two levels of reuse: reuse the overall template algorithm over and over. Basically, an entire set of steps that gets repeated as-is or reuse specific steps across one or more template algorithms.

Template method can be used in a variety of scenarios. For example, the following steps could be performed for handling requests:

  • validate input request using security token
  • standardize data – remove whitespaces, unify upper/lower case, correct misspelling
  • pre-processing e.g. transform request prior to processing
  • processing step – e.g. executing specific business logic
  • post processing e.g. transform response message in a specific format, encrypt sensitive data

Key question here: what are the variations in the above steps?
– authenticating requests – using a LDAP provider vs. using X509 certificates
– standardizing data – use custom implementation or open source tools to fix request data and perform pattern matching
– transformation: might vary by format (XML, plain text, JSON etc.)
– processing: might vary by use case

The security module itself could be used by other apps requiring authentication. the transformation module could be used for a batch process and processing logic could be reusable for more than one project as well. As always, it is key to keep the template algorithm simple, cohesive, and loosely coupled via well designed application programming interfaces.

Like this post? Subscribe to RSS feed or get blog updates via email.

tweet this add to del.icio.us post to facebook


Using Design Patterns To Build Reusable Assets

October 2, 2009

Design patterns are common solutions to design problems based on a given context. When used appropriately, they help address changing requirements. There are several books on design patterns and I don’t want to repeat that information here. Instead, we will look at design patterns in the context of building and integrating reusable assets. Here is a starter list:

  • Strategy – Polymorphically bind concrete implementations to execute a flavor of logic. This is useful when encapsulating product variations. If you need to support multiple flavors of a feature at runtime it is applicable. For instance, searching a product catalog feature could use exact text matching for product A while using fuzzy matching for product B. This could also be used to support multiple flavors within the same product and choosing a concrete implementation based on criteria. For this feature, it could be type of user or the nature of input parameter or volume of potential results.
  • Adapter – Used for translating one interface from another in order to integrate incompatible interfaces. This is useful in a couple of situations. Introduce an adapter when reusing a legacy asset. It is also useful when there are multiple versions of a reusable asset that you need to support in production. A single implementation can be reused to support the new version and the old version. The old version of the asset can be wrapped by an adapter for backward compatibility.
  • Template method – Used to define a generic set of steps to execute with placeholders for concrete steps that need customization. I tend to use this pattern for reusing business process flows across varying product types. It can also be used when implementing a standard request processing flow for both library components and web services. This is a common pattern when introducing horizontal concerns (such as security, logging, auditing etc.) as part of the processing algorithm.
  • Abstract factory – Used to build a family of products that need to be created as a cohesive unit. You also don’t want your calling code to know the nuances and complexity of constructing domain objects. This pattern is very useful when creating domain objects that require business rules and you want the complex creation in a single place in your codebase. I typically use this pattern with supporting bundling of product features. If you want to reuse a set of product features across bundles you will have several objects that all need to be carefully chosen at runtime for consistent behavior.
  • Decorator – Used with a core capability that you want to augment at runtime. Decorators are pluggable components that can be attached or detached at runtime. The upside is that the decorators and the component being decorated are both reusable but you want to watch out for object proliferation. I use this for pattern when the same data needs to be formatted or rendered differently or when you have a generic set of data fields that needs to be filtered based on some criteria.
  • Command – Used to encapsulate information that is used to call a piece of code repeatedly. Can also be used to support undo/redo functionality. The commands can be reusable across different product interfaces and act as entry points to invoke backend logic. For instance, I have used this pattern to support invocation of services from a self-service portal and interactive voice response channels.

There are additional patterns that help you organize your application code better (such as Model, View, Controller (MVC) and avoid point to point coupling between applications (publish/subscribe) fostering reuse.

what patterns have you used?

Like this post? Subscribe to RSS feed or get blog updates via email.

add to del.icio.us: Digg it : post to facebook: Stumble It! : :


Model View Controller Pattern and Reuse – Podcast Episode

August 16, 2009

Want to listen using iTunes?

Using iTunes?

podcast Just posted a new episode on the software reuse podcast series about the Model View Controller (MVC) pattern and how it helps with software reuse.

 

Like this post? Subscribe to RSS feed or get blog updates via email.

add to del.icio.us: Digg it : post to facebook: Stumble It! : :


Refactoring To Reuse #1

August 9, 2009

#1 Decouple connectivity from business logic

Often times you have a class that has a mixture of logic that is core or central to it and extraneous ones. A classic case is when you have a class that does calculations and also connects to a file or database. This isn’t bad per se because it probably works. But it inhibits reuse of both the calculation logic and the connectivity logic. One way to refactor the original class is to split it into 3 classes: a controller class, a connectivity class, and a calculation class. The controller is lightweight and co-ordinates the work across the other two classes. The connectivity class encapsulates file or database connectivity, and the calculation class executes a specific algorithm.

Here is an example – say you have a class named DiscountCalculator that accesses customer data from a database, and finds the ones that qualify for a particular promotional discount. You introduce a class named DBUtility that gets/closes a database connection, executes queries etc. I would advise against building such a class since good ones already exist. For example, if you use java, a better idea would be use Spring’s JDBCSupport and JDBCTemplate classes to achieve this. Now you can create a simple object (e.g. a plain old java object – POJO) that is returned from the database queries. The DiscountCalculator class can encapsulate the business logic within it or if you need to support multiple types of discountss you can consider introducing the Strategy design pattern. Whatever you decide, you can remove the database related logic from DiscountCalculator and keep it flexible for new types of discount calculations. In the same vein, the POJO is reusable as well for additional classes.

Like this post? Subscribe to RSS feed or get blog updates via email.

add to del.icio.us: Digg it : post to facebook: Stumble It! : :


%d bloggers like this: