我在代码中使用 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 添加到列表中,然后让其他线程池执行它们。
您希望实现的是工作者对象模式。我为您创建了一个小示例,展示如何通过特定命名模式拦截方法调用,但返回类型和参数可变。看我自己的答案在那里 https://stackoverflow.com/a/12130824/1082681一个更复杂的例子。
驱动程序应用:
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();
}
}
}
Output:
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
将工作对象添加到队列中,应用程序继续执行,无需proceed()
被召唤。为了便于说明,我添加了另一个建议,该建议在应用程序退出之前运行 FIFO 队列中的所有元素(可以根据您的需要使用其他队列类型)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)