java - AOP 使用Around 避免执行一个方法

标签 java spring aop spring-aop

我在我的代码中使用 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/

相关文章:

java - Spring 。使用@Bean 注册方面

java - AspectJ + @Configurable

java - TestNG 和 Selenium : Perform CRUD operations on entities with depedencies

java - 无法从 KafkaProducer 发布消息

java - Spring Web MVC Tiles 属性 'header' 未找到

java - 将 Angular 嵌入到 Spring 应用程序中并在运行 ngserve 时访问 Spring Controller

aop - Ninject 拦截 X 类的所有实例

java - Java 中的 "Too Many Connections"错误(MYSQLNonTransientConnectionException)

java - 如何使用 Spring 的 MailSender 发现电子邮件被退回

java - 使用 Spring Data JPA @LastModifiedDate 从审计中排除某些字段