同一包中的 @Around @Aspect 只能与 @DependsOn 一起使用

2024-02-13

请参阅下面的更新。


我有一个 Spring Boot 应用程序,我接受 TCP/IP 连接:

   public MyClass implements InitializingBean {
   @Override
    public void afterPropertiesSet() throws Exception {

        try (ServerSocket serverSocket = new ServerSocket(port)) {

            while (true) {

                Socket socket = serverSocket.accept();                   
                new ServerThread(socket).start();
            } 
        }
    }

    ...

    private class ServerThread extends Thread {
            @Override
            public void run() {
                try (InputStream input = socket.getInputStream();
                     OutputStream output = socket.getOutputStream()) {

                     // Read line from input and call a method from service:
                     service.myMethod(lineConvertedToMyObject);

                } catch {
                    ...
                }
            }
    }

}

现在效果很好,就这样。但是当我将 AspectJ 介绍给myMethod:

@Aspect
@Component
public class MyServiceAspect {

    private static final Logger logger = LoggerFactory.getLogger(MyServiceAspect.class);

    @Around(value = "execution(* com.package.to.MyService.myMethod(..))")
    public MyObject rules(ProceedingJoinPoint joinPoint) throws Throwable {

        long startTime = System.currentTimeMillis();

        MyObject obj = (MyObject) joinPoint.proceed();

        logger.debug("Took {} milliseconds", System.currentTimeMillis() - startTime);

        return obj;
    }
}

service.myMethod没有被调用并且线程被阻塞。我缺少什么?

Update:

所以这是交易:MyService, MyServiceImpl and MyServiceAspect都在同一个包中。移动MyServiceAspect到另一个包中使其工作。

这对任何人来说都敲响了警钟吗?很高兴向任何解释此行为的人提供赏金。谢谢!

更新2:

另一种解决方案:添加@DependsOn(value = {"myServiceAspect"})在之上MyServiceImpl再次解决了问题,但仍然想知道为什么。


实际问题

正如所描述的亚历山大·帕德林 >> https://stackoverflow.com/users/3985168/alexander-paderin在他对相关问题的回答中问题>> https://stackoverflow.com/questions/52518312/cacheable-doesnt-intercept-the-method-cache-is-always-empty/52609074#52609074中的无限循环afterPropertiesSet()是线程阻塞程序,因为控制权没有返回到Spring在这种情况下。

1.使用您的示例的工作示例(问题编辑后不是实际的)

您提供的代码示例不直接包含问题,AspectJ声明没问题。

首先,请让我分享一下工作示例:spring-aspectj-套接字 https://github.com/marme1ad/spring-aspectj-sockets。它是基于春季5.1.0 and 方面J 1.9.1(当前最新版本)并使用您的示例,其工作独立于位置/包MyServiceAspect.


2.问题说明

2.1.介绍

示例中最可能的线程阻止程序是调用ServerSocket.accept(),此方法的 javadocs 说:

侦听与此套接字建立的连接并接受它。该方法将阻塞,直到建立连接为止。

有2种正确的处理方法accept():

  1. 首先初始化连接,例如:

    serverSocket = new ServerSocket(18080);
    clientSocket = new Socket("127.0.0.1", 18080); // initializing connection
    Socket socket = serverSocket.accept(); // then calling accept()
    
  2. 设置等待接受的超时时间:

    serverSocket = new ServerSocket(18080);
    serverSocket.setSoTimeout(5000); // 5 seconds timeout
    Socket socket = serverSocket.accept(); // then calling accept()
    

    NOTE:如果5秒内没有连接,accept()会抛出异常,但不会阻塞线程

2.2.假设

我假设您正在使用第一种方法,并且在某处有一行初始化连接,即clientSocket = new Socket("127.0.0.1", 18080);.

但它被调用(例如,如果使用静态声明):

  • After serverSocket.accept()以防万一MyServiceAspect位于同一个包中并且
  • 之前 - 以防万一MyServiceAspect位于其他地方

3、调试

我不确定是否需要这样做,由于赏金的描述而有疑问,让我快速介绍一下,以防万一。

您可以使用调试您的应用程序远程调试- 它将涵盖方面、子线程、服务等。 - 您只需要:

  1. Run Java具有特定的参数,如本节中所描述的问题>> https://stackoverflow.com/questions/975271/remote-debugging-a-java-application
  2. 并使用IDE连接到指定的调试端口(步骤为Eclipse在同一问题中描述)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同一包中的 @Around @Aspect 只能与 @DependsOn 一起使用 的相关文章

  • 使用 google-api-java-client 的 2 足 OAuth

    有谁知道如何将 2 legged OAuth 与 google api java client 一起使用 我正在尝试访问 Google Apps 配置 API 以获取特定域的用户列表 以下不起作用 HttpTransport transpo
  • 具有最小刻度的图表的漂亮标签算法

    我需要手动计算图表的刻度标签和刻度范围 我知道漂亮刻度的 标准 算法 参见 我也知道这个Java实现 http erison blogspot nl 2011 07 algorithm for optimal scaling on char
  • 如何显示/隐藏jsf组件

    在我的一个 JSF 应用程序中 顶部的标题部分包含 selectOneMenu 底部的内容部分显示过滤器组件 默认情况下 应用程序首先在顶部显示 selectOneMenu 数据 在底部显示相应的 Filter 信息 如果用户选择不同的se
  • JFreeChart - 创建移动图表时出现问题

    我在我的 java 应用程序中使用 JFreeChart Problem 我想绘制一个XY面积图 whose 域轴 x 轴 当我们开始绘制数据时应该自动水平滚动 我在中看到了同样的事情时间序列图表但我不想要任何时间系列图表 我只想要滚动的
  • Java 中支持多少维数组,例如 a[1][1][1][1]....[1]? [复制]

    这个问题在这里已经有答案了 Java支持多少维数组a 1 1 1 1 1 我可以为数组声明无限数量的维度吗 数组维数限制为 255 有趣的是 JLS定义的Java编程语言没有这样的限制 但是你可以在JVM规范 http docs oracl
  • 处理 ANTLR 4 中的错误

    遵循后接受的答案 https stackoverflow com a 18137301 2279200的指示处理 ANTLR4 中的错误 https stackoverflow com q 18132078 2279200问题 我遇到了以下
  • “未找到 JAVA 路径。请检查 JAVA 是否已安装。”初始化 RSelenium 时出错

    我正在尝试启动一个 RSelenium 会话到 webscrape 但是 当运行此代码时 driver lt rsDriver browser c chrome chromever 76 0 3809 126 port 4444L 我收到此
  • 在 JavaFX 中更改 ListView 字体大小

    我想知道如何更改 JavaFx 中的列表视图项目文本字体大小 每行文本的大小会有所不同 我尝试使用细胞因子属性 但我不知道如何使用它 有人可以帮我吗 类似的问题在这里 如何更改JavaFX中ListView的字体大小 https stack
  • 如何使用键盘上的“删除”按钮作为从 JTable 中删除行的快捷方式[重复]

    这个问题在这里已经有答案了 可能的重复 如何制作删除按钮来删除JTable中的行 https stackoverflow com questions 13236206 how to make delete button to delete
  • 有界通配符相关的编译器错误

    我想知道这段代码有什么问题 Map 但我试图说得更具体 这个问题在这个旧的 Apache 线程 ht
  • 如何发现另一个应用程序的意图

    我正在尝试构建一个应用程序来接收来自 StumbleUpon 应用程序的共享 此时 我可以接收浏览器的 共享网址 但是当从 StumbleUpon 共享时 我的应用程序不会显示在列表中 我想我可能没有在清单中注册正确的意图 有什么方法可以找
  • Java XML 解析器添加不必要的 xmlns 和 xml:space 属性

    我在 Windows 10 上使用 Java 11 AdoptOpenJDK 11 0 5 2019 10 15 我正在解析一些旧版 XHTML 1 1 文件 这些文件采用以下一般形式
  • 通过 ssh 发送命令并读取输出结果

    我有代码通过 ssh 连接到远程服务器并向其发送 2 个或更多命令 例如 cd export home ops bin和 viewlinkload time 20131205 19 但我没有看到命令执行 也没有收到结果 我需要获取服务器返回
  • 找出该月第一个星期日/星期一等的日期

    我想在java中检测每个月第一周 第二周的第一个星期日 星期一的日期 我怎样才能实现它 我已经检查了 java 中的 Calendar 类和 Date 类 但无法找到解决方案 所以请帮助我解决这个问题 Calendar calendar C
  • 文档过滤器在 Java 中不起作用?

    在超过 10 个字符的文本字段中 它必须显示错误 为此 我使用了文档过滤器 JTextField field JTextField txtFld AbstractDocument document AbstractDocument fiel
  • Spring Boot中服务接口类的用途

    我的问题是关于接口类的使用 我对 Spring 还很陌生 所以如果这过于简单 请耐心等待 首先 当您可以在 BoxService 中声明 find all 时 这里拥有 IBoxService 接口有什么意义 其次 在控制器中如何使用IBo
  • 从数字列表中生成所有唯一对,n 选择 2

    我有一个元素列表 假设是整数 我需要进行所有可能的两对比较 我的方法是 O n 2 我想知道是否有更快的方法 这是我在java中的实现 public class Pair public int x y public Pair int x i
  • 在测试中替换 OAuth2 WebClient

    我有一个小型 Spring Boot 2 2 批次 用于写入 OAuth2 REST API 我已经能够配置WebClient下列的https medium com asce4s oauth2 with spring webclient 7
  • 混合语言源目录布局

    我们正在运行一个使用多种不同语言的大型项目 Java Python PHP SQL 和 Perl 到目前为止 人们一直在自己的私有存储库中工作 但现在我们希望将整个项目合并到一个存储库中 现在的问题是 目录结构应该是什么样的 我们应该为每种
  • 安装 JDK 时出错:keytool 命令需要已安装的 proc fs (/proc)。 Linux 的 Windows 子系统

    我尝试在 Linux 的 Windows 子系统 Ubuntu 14 04 上安装 Oracle JDK 1 7 但出现以下错误 the keytool command requires a mounted proc fs proc Jav

随机推荐