com.vbs.spring.versioning
Class VersioningAspect

java.lang.Object
  extended by com.vbs.spring.versioning.VersioningAspect
All Implemented Interfaces:
java.util.EventListener, org.springframework.beans.factory.config.BeanPostProcessor, org.springframework.context.ApplicationListener

public final class VersioningAspect
extends java.lang.Object
implements org.springframework.context.ApplicationListener, org.springframework.beans.factory.config.BeanPostProcessor

Intercepts any method calls on beans whose target class is annotated by VersionedClass, delegating the call to the correct versioned implementation where appropriate.

The call is only delegated if the active version in the current thread (obtained via VersionHolder.getActiveVersion()) is not null and an version dependent bean is available for the active version.

A version dependent bean is any bean whose target class is annotated by VersionDependentClass. The injected VersionDependentBeanResolver returns the version dependent bean if available.

If no version dependent bean is found, or if the method does not exist on the version dependent bean, the method on the intercepted bean is invoked.

Note that by default, a version dependent bean must exist for each target class defined for the intercepted bean and all methods on the inercepted bean must be present on each verion dependent bean. If this bean's target class is annotated as @lenient then not all version dependent beans may be present.

Addtionally, if a given version dependent bean is annotated as not @fullyImplemented , then not all methods may be present on that bean.

Only one instance of this bean should be configured within the spring container.

Author:
Mike Whitfield (mike@virtual-businesses.com)

Constructor Summary
VersioningAspect()
          Default constructor.
 
Method Summary
 java.lang.Object executeWithVersion(org.aspectj.lang.ProceedingJoinPoint joinPoint)
          Processes intercepted bean method calls.
 void onApplicationEvent(org.springframework.context.ApplicationEvent event)
          Attaches any beans registered as version dependent to the correct versioned bean.
 java.lang.Object postProcessAfterInitialization(java.lang.Object bean, java.lang.String beanName)
          Registers any relevant beans whose type is annotated by VersionedClass or VersionDependentClass.
 java.lang.Object postProcessBeforeInitialization(java.lang.Object bean, java.lang.String beanName)
          Performs no action.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

VersioningAspect

public VersioningAspect()
Default constructor.

Method Detail

postProcessAfterInitialization

public java.lang.Object postProcessAfterInitialization(java.lang.Object bean,
                                                       java.lang.String beanName)
                                                throws org.springframework.beans.BeansException
Registers any relevant beans whose type is annotated by VersionedClass or VersionDependentClass.

Protoype beans (and hence inner beans) are not registered.

Specified by:
postProcessAfterInitialization in interface org.springframework.beans.factory.config.BeanPostProcessor
Throws:
org.springframework.beans.BeansException

postProcessBeforeInitialization

public java.lang.Object postProcessBeforeInitialization(java.lang.Object bean,
                                                        java.lang.String beanName)
                                                 throws org.springframework.beans.BeansException
Performs no action.

Specified by:
postProcessBeforeInitialization in interface org.springframework.beans.factory.config.BeanPostProcessor
Throws:
org.springframework.beans.BeansException

onApplicationEvent

public void onApplicationEvent(org.springframework.context.ApplicationEvent event)
Attaches any beans registered as version dependent to the correct versioned bean.

Specified by:
onApplicationEvent in interface org.springframework.context.ApplicationListener

executeWithVersion

public java.lang.Object executeWithVersion(org.aspectj.lang.ProceedingJoinPoint joinPoint)
                                    throws java.lang.Throwable
Processes intercepted bean method calls.

The call is only delegated if the active version in the current thread (obtained via VersionHolder.getActiveVersion()) is not null and an version dependent bean is available for the active version.

Parameters:
joinPoint - defined the method to be called on the intercepted bean.
Returns:
the object returned by the method call, either on the intercepted bean or it's version dependent delegate.
Throws:
java.lang.Throwable - any exception thrown from within the intercepted method call.