Fluent interface / DSL für @AspectJ Style AOP Pointcut Definitionen

Thomas Darimont

Erfahrenes Mitglied
Hallo,

anstatt wie in normalem @AspectJ-Style AOP:
http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html
den Pointcut Ausdruck in der Pointcut Annotation an einer "dummy" Methode als String mitzugeben: (Syntax ist nicht korrekt, nur ein kleines Beispiel...)
Java:
@Pointcut("call(@Transactional * * de.tutorials..*.process*(*,int,@NotNull String)) && !within(de.tutorials.aop..*) && args(args,param0,param1)")

Könnte man auch ein "Fluent Interface" bzw. eine DSL (Domain Specific Language) für Pointcuts Definieren, welches man dazu verwendet um Pointcuts zu beschreiben.

Java:
/**
 * 
 */
package de.tutorials.aop.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import de.tutorials.aop.Any;
import de.tutorials.aop.Arguments;
import de.tutorials.aop.NotNull;
import de.tutorials.aop.Pointcut;
import de.tutorials.aop.Pointcuts;
import de.tutorials.aop.Transactional;

/**
 * @author Thomas.Darimont
 * 
 */
@Aspect
public class Retry {

	int maxRetries;

	public int getMaxRetries() {
		return maxRetries;
	}

	public void setMaxRetries(int retryLimit) {
		this.maxRetries = retryLimit;
	}

	
	public Pointcut someMethods() {
		return Pointcuts
					.call()
					.methods("process*")
					.withinPackage("de.tutorials.services..")
					.withAttribute(Transactional.class)
					.withArguments(
						new Arguments() {
							Any args; //Any -> special Typ matching all types like "*"
							int param0;
							@NotNull String param1;
						})
					.combine(
							Pointcuts
							.not()
							.within("de.tutorials.aop..")
							);
	}

   @Around(value="someMethods")
	public Object retry(ProceedingJoinPoint thisJoinPoint) {
		int currentTry = 0;
		while (currentTry < maxRetries) {
			try {
				return thisJoinPoint.proceed();
			}catch(Throwable throwable){
				//log ...
				currentTry++;
			}
		}
		throw new RuntimeException("retry limit reached");
	}
}

Das bietet dann gleich mehrere Vorteile auf einmal:
* Der Compiler kann die Syntax checken :)
* Code completion
* Pointcutausdrücke sind Refactoring friendly
* AspectJ könnte verwendet werden um diese Art Syntax zur Kompilierungszeit zu validieren (via declare Error/Warning...)

Gruß Tom
 
Zurück