AOP 使用 around 来避免执行方法

2024-04-29

我在代码中使用 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(使用前将#替换为@)

AOP 使用 around 来避免执行方法 的相关文章

随机推荐

  • 从 URL 中删除文件扩展名

    我从未使用过 mod rewrite 但我想从网站的网址中删除所有文件扩展名 我需要遵循什么规则才能做到这一点 我已经尝试过这个 但是每次我单击网站上的链接时都会出现内部错误 RewriteRule 1 php L Options Mult
  • 使用 client_body_in_file_only 进行 nginx 文件上传

    晚上好 我需要将静态内容上传到 nginx 服务器 1 9 因此上传模块不适用于此版本 我读过这篇文章 Nginx 直接文件上传 无需通过后端传递 https coderwall com p swgfvw nginx direct file
  • WPF 动画第一次不运行

    我有一个窗口 其目的是在显示时淡入 第一次使用时 动画不会运行 在后续使用中 效果很好 这是一个请求者 我实例化它来显示一些东西 我不会保留它并重新使用实例 我实例化请求者 设置各种属性 例如 Top 和 Left 然后调用 ShowDia
  • MKMapview 将图钉放置在位置(长/纬度)

    我有纬度和长值 我需要能够在这个位置放置图钉 有人可以提供一些关于如何解决这个问题的建议吗 找到下面非常简单的解决方案 将引脚放置在由以下定义的给定位置CL位置坐标二维 http developer apple com library ma
  • 在 JAXB 或 Xstream 中,是否可以在解组期间过滤掉类型/值上的某些子元素

    希望大家都好 快速提问看看是否有人有任何反馈 过去两天我正在尝试 JaxB 和 Xstream 我基本上使用 XML 库将 XML 编组到 Java 对象或从 Java 对象中解组 这是一项非常简单的任务 我很快就完成了 但是 我想要解组到
  • 当用户应该有权访问他拥有的交易时,Rspec 测试失败,用户被重定向

    在我的应用程序中 借助 Cancan 我允许客户访问他自己的优惠 当我用浏览器 手动 尝试时它有效但我未能实施 rspec 测试 客户无法访问其他客户的交易 只能访问他自己的交易 管理员通过 Active Admin 界面授予他访问权限 就
  • 重用 CloudBlobClient 对象

    我有这两个对象用于 Azure Blob 存储访问 并希望在 ASP NET MVC 应用程序中使用它们 CloudBlobClient blobClient storageAccount CreateCloudBlobClient Clo
  • jQuery Masonry 和媒体查询 - 重新加载 masonry

    我的网站设计有媒体查询 以覆盖不同大小的布局 我有砌体组织一堆全尺寸宽度的浮标 没问题 在移动宽度下 所有浮子都会浮起并堆叠在一起 所以我只需要在网站大小调整为平板电脑布局且 768px
  • Struts 2 S2-016 漏洞缓解直至升级

    最近 Struts 修复了一个允许攻击者执行远程代码的漏洞 显然 不修补这个问题就像用潮流欢迎黑帽子一样 http struts apache org release 2 3 x docs s2 016 html http struts a
  • R 中自定义函数的自动创建和使用

    我想在 for 循环中创建评估不同的索引 这些指数有不同的公式 并不总是需要评估 f i 我要评估的指数可能是 a 1 b 2 c 5 d 8 IDX1 function a b result a b IDX2 function c b r
  • 故事板放大/缩小键盘快捷键

    Xcode 中可以使用什么快捷键组合来放大和缩小 是的 我知道这是一个愚蠢的问题 但谷歌搜索没有给我任何结果 甚至 Xcode 键盘快捷键也没有给我太多信息 也许我必须要求为 Xcode 4 5 提供更好的更新键盘快捷键文档 你也可以用鼠标
  • 流星和陨石(mrt)有什么区别?

    例如 有些网站告诉我使用mrt add accounts ui 使用陨石 对吧 其他人说meteor add accounts ui 据我了解 陨石 https github com oortcloud meteorite只是一个版本控制
  • “key”是MySqli中的保留字吗?我收到错误

    我刚刚真正接触 MySql MySqli 并且正在使用准备好的语句 除了这一行之外 我的整个脚本运行良好 if stmt con gt prepare SELECT bandHash userHash userPassHash type F
  • WinForms 与 mshtml 和 ie9 的问题

    IE9 似乎破坏了我的 32 位 winforms net 3 5 应用程序中基于 mshtml com 的 WebBrower html 编辑器 由于我必须使用 activex USB 设备控制器 它必须设置为 32 位 该错误不稳定 它
  • Python 中使用 RegEx 的函数解析器

    我有一个 Fortran 源代码 几乎不相关 我想解析函数名称和参数 例如使用 w with a b 1 2 2 c 3 4 我得到以下信息 如预期 b 1 2 2 c 3 4 我需要的地方 a b 1 2 2 c 3 4 b 1 2 2
  • 类验证器不验证数组

    我无法让类验证器工作 看起来我没有使用它 一切都像我没有使用类验证器一样工作 当发送正文格式不正确的请求时 我没有任何验证错误 尽管我应该这样做 My DTO import IsInt Min Max from class validato
  • Docker 与 nginx 组合不断显示欢迎页面

    我是新来的docker并尝试使用最简单的 docker compose yml 显示一个 hello world 页面 并在此基础上构建最终完整的LEMP堆栈它将与我的服务器具有相同的配置 然而大多数教程已经过时 并且有很多使用方法dock
  • 命名空间“System”中不存在类型或命名空间名称“Serialized”(您是否缺少程序集引用?

    I am VS 2012 silverlight 5 beginner I tried to serialize and de serialize from a xml file I have following error while d
  • java有索引的最小优先级队列吗?

    我需要它来实现 Dijkstra 算法 并且我确实有自己的实现 但是使用 java 自己的类记录我的代码会更容易 不 Java标准库没有这样的数据结构 我想大多数人都用这个 http algs4 cs princeton edu 24pq
  • AOP 使用 around 来避免执行方法

    我在代码中使用 Spring AOP 来拦截某个方法的执行 我正在尝试做的一个简化示例如下 public void someMethod does something Around execution someMethod public v