您希望实现的是工作对象模式。我为您创建了一个小示例,展示如何通过某种命名模式拦截方法调用,但使用可变的返回类型和参数。有关更复杂的示例,请参见我自己的答案。
驱动应用:
public class Application {
public static void main(String[] args) {
System.out.println("Starting up application");
Application app = new Application();
app.doThis(11);
app.doThat();
app.doThis(22);
System.out.println("Shutting down application");
}
public void doThis(int number) {
System.out.println("Doing this with number " + number);
}
public String doThat() {
String value = "lorem ipsum";
System.out.println("Doing that with text value '" + value + "'");
return value;
}
}
实现工作对象模式的方面:
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Callable;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class QueuedExecutionAspect {
Queue<Callable<Object>> waitList = new LinkedList<Callable<Object>>();
private void addToWaitList(Callable<Object> callable) {
waitList.add(callable);
}
@Around("execution(public * Application.do*(..))")
public Object anotherMethod(final ProceedingJoinPoint joinPoint) {
System.out.println(joinPoint + " -> adding to execution queue");
addToWaitList(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
joinPoint.proceed();
} catch (Throwable e) {
throw new Exception(e);
}
return null;
}
});
return null;
}
@After("execution(public * Application.main(..))")
public void doDelayedExecution(JoinPoint joinPoint) throws Exception {
System.out.println("\nDelayed executions:");
while (!waitList.isEmpty()) {
waitList.poll().call();
}
}
}
输出:
Starting up application
execution(void Application.doThis(int)) -> adding to execution queue
execution(String Application.doThat()) -> adding to execution queue
execution(void Application.doThis(int)) -> adding to execution queue
Shutting down application
Delayed executions:
Doing this with number 11
Doing that with text value 'lorem ipsum'
Doing this with number 22
从输出中可以看出,在将工作对象添加到队列@Around
后,通知正常终止,应用程序继续执行而没有被调用。为了说明,我添加了另一个建议,它在应用程序退出之前运行 FIFO 队列中的所有元素(可以根据您的需要使用其他队列类型)。Callable
proceed()