我在我的代码中使用 Spring AOP 来拦截某个方法的执行。我正在尝试做的一个简化示例如下:
public void someMethod() {
//does something
}
@Around("execution( someMethod())")
public void anotherMethod(final ProceedingJoinPoint joinPoint) {
//i want to add this to a queue to get executed later on
addToWaitList(new Callable() {
@Override
public call() throws Exception {
joinPoint.proceed();
}
});
return;
}
本质上,我想推迟
someMethod()
的执行直到它位于列表的头部。然而,主线程阻塞了,即使我在 anotherMethod()
末尾返回,所以我无法添加 new Callable
到列表,直到第一个完成执行。文档说你可以通过返回自己的返回值或抛出异常来缩短建议的方法执行。我不想抛出异常并且不确定在这种情况下“返回自己的返回值”是什么意思。我希望能够将 Callables 添加到主线程的列表中,然后让其他一些线程池执行它们。
最佳答案
您希望实现的是 worker 对象模式 .我为您创建了一个小示例,展示了如何通过特定命名模式拦截方法调用,但具有可变返回类型和参数。见 my own answer there一个更复杂的例子。
驱动申请:
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;
}
}
实现 worker 对象模式的方面:
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
添加 Callable
后,通知正常终止worker 对象添加到队列中,应用程序继续执行而没有 proceed()
被调用了。为了说明,我添加了另一个建议,它在应用程序退出之前运行 FIFO 队列中的所有元素(可以根据您的需要使用其他队列类型)。
关于java - AOP 使用Around 避免执行一个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17114843/