AOP使用Around来避免执行方法

我在我的代码中使用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添加到列表中,直到第一个完成执行。

文档说您可以通过返回自己的返回值或抛出exception来快速建议的方法执行。 我不想抛出exception而且我不确定在这种情况下“返回自己的返回值”意味着什么。 我希望能够使用主线程将Callables添加到列表中,然后让其他线程池执行它们。

您希望实现的是工作对象模式 。 我已经创建了一个小例子,展示了如何通过某种命名模式拦截方法调用,但是具有可变的返回类型和参数。 有一个更复杂的例子,请参阅我自己的答案 。

司机申请:

 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对象模式的Aspect:

 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> waitList = new LinkedList>(); private void addToWaitList(Callable 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() { @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 

从输出中可以看出,在将Callable工作者对象添加到队列后, @Around建议正常终止,应用程序执行继续,而没有调用proceed() 。 为了说明,我添加了另一个建议,它在应用程序退出之前运行FIFO队列中的所有元素(可以根据您的需要使用其他队列类型)。