记录在Spring boot项目中使用@Async注解,但是没有生效的排查。

简介 背景:我的代码中:查看执行结果:页面F12查看耗时:为什么异步提交耗时这么久?您观察到的耗时问题非常关键!异步提交耗时:7962 意味着异步方法实际上是在主线程同步执行的,并没有真正异步化。这通常是由SpringAOP的代理机制失效引起的。根本原因分析方法内部自调用(Self-Invocation)失效@Async 是基于SpringAOP动态代理实现的。只有当通过代理对象调用

🔔🔔好消息!好消息!🔔🔔

有需要的朋友👉:微信号 kaigejava2022

背景:

我的代码中:

查看执行结果:

页面F12查看耗时:

为什么异步提交耗时这么久?

您观察到的耗时问题非常关键!异步提交耗时:7962 意味着异步方法实际上是在主线程同步执行的,并没有真正异步化。这通常是由 Spring AOP 的代理机制失效引起的。

根本原因分析

  1. 方法内部自调用 (Self-Invocation) 失效

    • @Async 是基于 Spring AOP 动态代理实现的。

    • 只有当通过代理对象调用方法时,AOP 拦截器才会生效,从而将任务提交给线程池。

    • 如果在同一个类中,方法 A 直接调用方法 B(即使 B 标记了 @Async),调用的是原始对象的方法,绕过了代理,导致异步失效,变成同步调用。

  2. 检查您的代码

    • 在 InspectionTasksController 中,您注入了 IAsyncRiskAnalysisService 接口。

    • 调用代码:asyncRiskAnalysisService.executeRiskAnalysisAsync(...)

    • 这看起来是正确的外部调用,理论上应该走代理。

但是,既然耗时这么长,说明一定是同步执行了。我们需要排查以下几点:

  1. 异步配置是否开启?

    • 检查启动类或配置类上是否有 @EnableAsync 注解。如果没有,@Async 只是一个摆设。

  2. 线程池是否配置正确?

    • 检查 ThreadPoolConfig 中是否正确定义了名为 threadPoolTaskExecutor 的 Bean。

  3. 类是否被 Spring 管理?

    • AsyncRiskAnalysisServiceImpl 上有 @Service 注解,应该是受管的。

解决方案

请按照以下步骤检查和修复:

第一步:检查 @EnableAsync

请搜索整个项目,确认是否有 @EnableAsync 注解。通常它应该在启动类 SuperviseAiApplication.java 或某个配置类(如 ThreadPoolConfig.java)上。

查看启动类,果然没有@EnableAsync 注解。

第二步:强制使用 AOP 代理(如果第一步没问题)

如果配置都开启了,但依然同步,可能是 Spring 容器加载顺序或代理方式的问题。


总结:

使用@Async 注解的是,记得需要在启动类上添加  @EnableAsync 注解 。告诉spring boot ,我要开启异步了。 


TopTop