• [ << ]
  • [ 0 ]
  • [ 1 ]
  • [ 2 ]
  • [ 3 ]
  • [ >> ]
Jun '04
28
Definiƫren van PointCuts en Advice

Met de introductie van de Wrapper is het zo dat alle methoden over 1 kam geschoren worden. Dat wil zeggen ze worden allemaal gelogd naar de standaard uitvoer. Om selectief te kunnen zijn hebben we iets van een trigger nodig waarbij er bij sommige methoden wel wat gebeurt en bij andere niet of wat anders.

Dit mapt verassend goed boven op de Pointcut en Advice concepten van AOP. Misschien moesten we dan daarom maar 2 klasjes maken die dat vertegenwoordigen.

De verantwoordelijkheid van een Pointcut is het detecteren of een methode aanroep wel of niet voorzien moet worden van een stukje Advice. Advice bevat de extra code die voor, na, bij een fout of in plaats van de eigenlijke implementatie moet. Een mogelijke implementatie staat hieronder. Hier is het default gedrag weg gestopt in around(), welke een soortgelijk blok vormt zoals AspectJ zijn code genereert. Eerst de before call, dan de eigenlijke methode en dan de after call.
                
 public abstract class Advice {
 
	public abstract void before(Method m,
		Object[] args);
	public abstract Object after(Method m,
		Object[] args,
		Object result);
	public abstract Throwable exception(
		Method m,
		Object[] args,
		Throwable fault);

	public Object around(Object target,
		Method m,
		Object[] args) throws Throwable {
	 try {
		before(m,args);
		Object result=m.invoke(target,args);
		return after(m,args,result); 
	 } catch (InvocationTargetException ex) {
		Throwable t=ex.getTargetException();
		throw exception(m,args,t);
	 } 
	} 	
 }

                
Pointcut is eigenlijk heel simpel, we hebben een methode en we willen weten of een specifiek Pointcut hierop van toepassing is. Hiertoe volstaat de volgende interface. In de implementaties kunnen dan allerlei smart-ass reguliere expressies geplaatst worden (leef je uit :-).
                
 public interface Pointcut {
	public boolean qualifies(Method m);
 } 

                
Nu moet alleen nog de Wrapper worden uitgebreid worden zodat deze kijkt of er een pointcut beschikbaar is voor een specifieke methode, in welk geval het Advice moet worden uitgevoerd. De onderstaande implementatie verondersteld 2 Lists van gelijke lengte : pointcuts en advices.
                 
 public Object invoke(Object proxy, 
		Method method, 
		Object[] args) throws Throwable {
	//
	Method m=myDelegate.getClass().
	 getMethod(
	 method.getName(),
	 method.getParameterTypes()
	 );
	//
	// See if there is a Pointcut for this method and 
	// invoke the associated Advice if so.
	//
	for (int t=0;t<pointcuts.size();t++) {
		if (((Pointcut)pointcuts.get(t)).qualifies(method)) {
			return ((Advice)advices.get(t)).around(myDelegate,method,args);
		}
	}
	//
	// No pointcut was found, so fire the method as normal. 
	//
	try {
		return method.invoke(myDelegate,args);
	} catch (InvocationTargetException ex) {
		Throwable t=ex.getTargetException();
		throw t;
	} 
 } 

                
Dit is een mooi moment om de source code te downloaden en te kijken naar de Demo :-)
  • [ << ]
  • [ 0 ]
  • [ 1 ]
  • [ 2 ]
  • [ 3 ]
  • [ >> ]