AspectChainModifier

To influence the aspect stack that is executed before and after a business call an application can configure an interception class that is allowed to modify the aspect stack before it is handed out to the presentation layer. You can do this by specifying the property aspect.chain.modifier.class.name in configuration.properties. The application needs to specify the fully qualified class name of a class that implements the AspectChainModifier interface. This is interface defines a very simple hook method modifyChain. The argument to this function is the first aspect in the chain. Any aspect implements the Aspect interface, and must thus be linkable to subsequent aspects. By analyzing the sequence of aspects and modifying the chain, the application can add, remove and replace the standard jZeno aspects.

The last aspect in the chain will be a DelegationAspect that delegates the call to the decorated business facade. This is important if you want to add an aspect to the end of the chain, because you should still insert it before the last element in the chain. (Otherwise the delegation aspect would invoke the business facade before your new aspect gets called).


Example

In the example below our application requires more control on the creation of hibernate sessions. In order to do this it configures the MyModifier class (below) in it's configuration.properties file (aspect.chain.modifier.class.name=modify.chain.MyModifier). This aspect chain modifier will loop through the standard jZeno aspects and will replace the default TransactionAspect with a custom one (MyTransactionAspect).


package modify.chain;

import net.sf.jzeno.aop.Aspect;
import net.sf.jzeno.aop.AspectChainModifier;
import net.sf.jzeno.aop.TransactionAspect;

public class MyModifier implements AspectChainModifier {
	private static final long serialVersionUID = 1L;

	public Aspect modifyChain(Aspect first) {
		Aspect ret = first;
		
		Aspect previous = null;
		Aspect current = first;
		while(current != null) {
			if(current instanceof TransactionAspect) {
				// Create new custom transaction aspect.
				MyTransactionAspect mta = new MyTransactionAspect(...);
				
				// Replace default transaction aspect.
				mta.setNextAspect(current.getNextAspect());
				if(previous != null) {
					previous.setNextAspect(mta);
				} else {
					ret = mta;
				}
				break;
			}
			
			previous = current; 
			current = current.getNextAspect();
		}
		
		return ret;
	}    
}