AOP使用Around来避免执行方法 [英] AOP Using Around to avoid executing a method

查看:1382
本文介绍了AOP使用Around来避免执行方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的代码中使用Spring AOP来拦截某个方法的执行。我正在尝试做的简化示例如下:

I am using Spring AOP in my code to intercept the execution of a certain method. A simplified example of what I'm trying to do is below:

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 到列表,直到第一个完成执行。

Essentially, I want to hold off the execution of someMethod() until it is at the head of the list. However, the main thread blocks, even though I return at the end of anotherMethod(), so I am unable to add a new Callable to the list until the first one is done executing.

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

The documentation says you can shortcut the advised method execution by returning its own return value or throwing an exception. I don't want to throw an exception and am not really sure what "returning its own return value" means in this case. I want to be able to add the Callables to the list with the main thread and then have some other threadpool executing them.

推荐答案

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

What you wish to implement is the worker object pattern. I have created a small example for you showing how you can intercept method calls with by a certain naming pattern, but with variable return types and parameters. See my own answer there for a more complex example.

驱动程序应用程序:

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();
        }
    }
}

输出:

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

As you can see from the output, the @Around advice terminates normally after having added the Callable worker object to the queue, application execution continues without proceed() having been called. For illustration I added another advice which runs all elements from the FIFO queue (other queue types can be used according to your needs) before the application exits.

这篇关于AOP使用Around来避免执行方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆