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
输出:
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队列中的所有元素(可以根据您的需要使用其他队列类型)。