深入了解Spring Boot中@Async注解的8大坑点

文章目录

    • 1. 缺少@EnableAsync注解
    • 2. 异步方法需独立
    • 3. 不同的异步方法间无法相互调用
    • 4. 返回值为void的异步方法无法捕获异常
    • 5. 外部无法直接调用带有@Async注解的方法
    • 6. @Async方法不适用于private方法
    • 7. 缺失异步线程池配置
    • 8. 异步方法与事务的兼容
    • 结语

在这里插入图片描述

🎉深入了解Spring Boot中@Async注解的8大坑点


  • ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹
  • ✨博客主页:IT·陈寒的博客
  • 🎈该系列文章专栏:架构设计
  • 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习
  • 🍹文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️

Spring Boot是一个流行的Java开发框架,提供了丰富的功能和便捷的配置,使得开发者可以更专注于业务逻辑。在异步编程方面,Spring Boot提供了@Async注解,它能够让方法异步执行,提高系统的并发性能。然而,在使用@Async注解时,有一些潜在的坑需要注意。本文将深入探讨Spring Boot中使用@Async注解时可能遇到的8大坑点,并提供相应的解决方案。
在这里插入图片描述

1. 缺少@EnableAsync注解

在使用@Async注解之前,必须在Spring Boot应用程序的主配置类上添加@EnableAsync注解,以启用异步方法的支持。如果忽略了这一步,@Async注解将不会生效。

@SpringBootApplication
@EnableAsync
public class YourApplication {public static void main(String[] args) {SpringApplication.run(YourApplication.class, args);}
}

2. 异步方法需独立

@Async注解修饰的方法不能直接被同一个类中的其他方法调用。因为Spring会在运行时生成一个代理类,调用异步方法时实际上是调用这个代理类的方法。因此,如果在同一个类中直接调用异步方法,@Async注解将不会生效。

@Service
public class YourService {@Asyncpublic void asyncMethod() {// 异步执行的逻辑}public void callingAsyncMethod() {// 直接调用asyncMethod将无法异步执行asyncMethod();}
}

解决方案是通过注入YourService的代理对象来调用异步方法。

@Service
public class YourService {@Autowiredprivate YourService self;@Asyncpublic void asyncMethod() {// 异步执行的逻辑}public void callingAsyncMethod() {// 通过代理对象调用异步方法self.asyncMethod();}
}

3. 不同的异步方法间无法相互调用

在同一个类中,一个异步方法调用另一个异步方法,也会出现不会异步执行的问题。这是由于Spring默认使用基于代理的AOP来实现异步方法,代理对象内部的方法调用不会触发AOP拦截。

@Service
public class YourService {@Asyncpublic void asyncMethod1() {// 异步执行的逻辑}@Asyncpublic void asyncMethod2() {// 异步执行的逻辑asyncMethod1(); // 这里调用将不会异步执行}
}

解决方案是通过AopContext.currentProxy()获取当前代理对象,再调用异步方法。

@Service
public class YourService {@Autowiredprivate YourService self;@Asyncpublic void asyncMethod1() {// 异步执行的逻辑}@Asyncpublic void asyncMethod2() {// 异步执行的逻辑self.asyncMethod1(); // 通过代理对象调用将异步执行}
}

4. 返回值为void的异步方法无法捕获异常

如果使用@Async注解的异步方法的返回值为void,那么这个方法中抛出的异常将无法被捕获。这是因为在异步方法的调用线程和实际执行异步方法的线程之间无法传递异常。

@Service
public class YourService {@Asyncpublic void asyncMethod() {// 异步执行的逻辑throw new RuntimeException("Async method exception");}
}

解决方案是将返回值设置为Future,这样就可以在调用get()方法时捕获到异常。

@Service
public class YourService {@Asyncpublic Future<Void> asyncMethod() {// 异步执行的逻辑throw new RuntimeException("Async method exception");}
}

在调用异步方法时,可以通过Futureget()方法捕获到异常。

@Service
public class YourService {@Autowiredprivate YourService self;public void callAsyncMethod() {try {self.asyncMethod().get();} catch (Exception e) {// 捕获异常}}
}

5. 外部无法直接调用带有@Async注解的方法

如果在同一个类中直接调用带有@Async注解的方法,是无法异步执行的。因为Spring会在运行时生成一个代理类,外部直接调用实际上是调用的原始类的方法,而不是代理类的方法。

@Service
public class YourService {@Asyncpublic void asyncMethod() {// 异步执行的逻辑}
}@Service
public class AnotherService {@Autowiredprivate YourService yourService;public void callAsyncMethod() {// 外部直接调用asyncMethod将无法异步执行yourService.asyncMethod();}
}

解决方案是通过注入YourService的代理对象来调用异步方法。

@Service
public class YourService {@Autowiredprivate YourService self;@Asyncpublic void asyncMethod() {// 异步执行的逻辑}
}@Service
public class AnotherService {@Autowiredprivate YourService self;public void callAsyncMethod() {// 通过代理对象调用异步方法self.asyncMethod();}
}

6. @Async方法不适用于private方法

@Async注解只对公有方法有效,因此`private

方法无法异步执行。如果尝试给一个private方法添加@Async`注解,将不会产生任何效果。

@Service
public class YourService {@Asyncprivate void asyncMethod() {// 这里的@Async注解将不会生效}
}

解决方案是将要异步执行的逻辑抽取到一个公有方法中,并在私有方法中调用这个公有方法。

@Service
public class YourService {@Asyncpublic void asyncMethod() {doAsyncMethod();}private void doAsyncMethod() {// 异步执行的逻辑}
}

7. 缺失异步线程池配置

在使用@Async注解时,Spring Boot默认会创建一个线程池来执行异步方法。如果没有进行配置,默认使用的是SimpleAsyncTaskExecutor,这是一个单线程的执行器,可能会导致性能瓶颈。

为了解决这个问题,可以配置一个合适的线程池。以下是一个示例的配置:

@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
}

这个配置使用了ThreadPoolTaskExecutor,并设置了核心线程数、最大线程数、队列容量等参数,根据实际情况进行调整。

8. 异步方法与事务的兼容

在默认情况下,使用@Async注解的方法与事务是不兼容的。因为在使用事务的方法中调用使用@Async注解的方法时,事务将无法传播到异步方法中,异步方法将在没有事务的情况下执行。

解决方案是将@Async注解添加到另外一个类的方法上,通过代理对象来调用异步方法。

@Service
public class YourService {@Autowiredprivate AsyncService asyncService;@Transactionalpublic void transactionalMethod() {// 在事务中调用异步方法asyncService.asyncMethod();}
}@Service
public class AsyncService {@Asyncpublic void asyncMethod() {// 异步执行的逻辑}
}

通过将异步方法移动到另一个类中,可以确保异步方法在新的事务中执行,与外部事务不会产生冲突。

结语

使用@Async注解能够提高系统的并发性能,但在使用时需要注意一些潜在的问题。通过深入了解Spring Boot中@Async注解的这8大坑点,并采取相应的解决方案,可以更好地应用异步编程,确保系统的可靠性和性能。希望本文对您理解和使用Spring Boot中的异步注解有所帮助。


🧸结尾 ❤️ 感谢您的支持和鼓励! 😊🙏
📜您可能感兴趣的内容:

  • 【Java面试技巧】Java面试八股文 - 掌握面试必备知识(目录篇)
  • 【Java学习路线】2023年完整版Java学习路线图
  • 【AIGC人工智能】Chat GPT是什么,初学者怎么使用Chat GPT,需要注意些什么
  • 【Java实战项目】SpringBoot+SSM实战:打造高效便捷的企业级Java外卖订购系统
  • 【数据结构学习】从零起步:学习数据结构的完整路径

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/182667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ros报错:The Plugin for class ‘jsk_rviz_plugin/Plotter2D‘ failed to load

一般出现这种情况&#xff0c;是提醒Ros缺少某种库&#xff1a; 图中显示的错误是说明少了jsk_rviz_plugins库&#xff0c;他是一个提供原始rviz插件的包。 解决办法是安装相应的库与插件&#xff1a; #根据自己ROS的版本选择相应的指令 # ubuntu20.04:noetic sudo apt-get i…

RabbitMQ消息的应答

消息的应答机制 消费者完成一个任务可能需要一段时间&#xff0c;如果其中一个消费者处理一个长的任务并仅只完成了部分突然它挂掉了&#xff0c;会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息&#xff0c;便立即将该消息标记为删除。在这种情况下&#xff0c;突然有个…

计算机视觉:使用dlib实现人脸检测

1 dlib介绍 Dlib是一个广泛使用的开源库&#xff0c;在计算机视觉和机器学习领域具有重要影响。它是由Davis King在2002年开发&#xff0c;主要用C语言编写&#xff0c;但也提供了Python接口。Dlib结合了高效的算法和易用性&#xff0c;使其成为学术界和工业界的热门选择。 1.…

SpringBoot项目启动后自动停止了?

1 现象 2023-11-22T09:05:13.36108:00 DEBUG 17521 --- [ main] o.s.b.a.ApplicationAvailabilityBean : Application availability state LivenessState changed to CORRECT 2023-11-22T09:05:13.36208:00 DEBUG 17521 --- [ main] o.s.b.a.Applicat…

一文1000字彻底搞懂Web测试与App测试的区别

总结分享一些项目需要结合Web测试和App测试的工作经验给大家&#xff1a; 从功能测试区分&#xff0c;Web测试与App测试在测试用例设计和测试流程上没什么区别。 而两者的主要区别体现在如下几个方面&#xff1a; 1 系统结构方面 Web项目&#xff0c;B/S架构&#xff0c;基…

Android中实现RecyclerView,并对item及其多个子控件的点击事件监听

目录 背景 实现RecyclerView 第一步、 新建item的xml 第二步、在activity的布局中引入 RecyclerView 第三步、新建一个adapter 第四步、在activity中初始化绑定adapter即可 实现item及其多个子组件点击事件监听 第一步、 适配器中创建监听对象 第二步、适配器中绑定监听…

uniapp ios 授权弹窗 uniapp弹出框怎么实现

新版本的信息弹窗组件 可以弹出很多条信息&#xff0c;并单独控制消失时间、点击消失。 用循环来生成很多个弹窗&#xff0c;用this.$refs来传值&#xff0c;并添加数组。 1.布局 2.js 具体流程。需要一个弹窗&#xff0c;基本信息传入组件&#xff0c;处理后添加入数组&am…

智能优化算法应用:基于闪电搜索算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于闪电搜索算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于闪电搜索算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.闪电搜索算法4.实验参数设定5.算法结果6.参考…

【C++】异常处理 ① ( 异常概念引入 | 抛出异常语法 | 捕获异常语法 | 异常捕获流程 | 异常处理代码示例 )

文章目录 一、异常处理1、异常概念引入2、抛出异常语法3、捕获异常语法4、异常捕获流程 二、异常处理代码示例1、错误代码示例 - 抛出异常 / 不捕获异常2、正确代码示例 - 抛出异常 / 捕获异常3、正确代码示例 - 抛出异常 / 捕获异常不处理继续抛出异常 一、异常处理 1、异常概…

接口测试入门8问(含答案+文档)

Q1&#xff1a;什么是接口测试&#xff0c;基础知识什么的讲讲吧&#xff01; A&#xff1a;你好&#xff0c;接口可以分下面几种 1、系统与系统之间的调用&#xff0c;比如银行会提供接口供电子商务网站调用&#xff0c;或者说&#xff0c;支付宝会提供接口给淘宝调用 2、上…

Table和HashBasedTable的使用案例

------------------- 1.普通使用 package org.example.testhashbasedtable;import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table;import java.util.Map;public class TestHashBasedTable {public static void main(String[] args) {Ta…

【方法】PowerPoint如何删除“限制编辑”?

如果PPT文件设置成“只读模式”&#xff0c;就会被限制编辑&#xff0c;也就是无法对PPT进行编辑或更改&#xff0c;那要如何删除这个“限制”呢&#xff1f; 下面小编会按照“无密码的只读方式”、“有密码的只读方式”以及“忘记了密码的只读方式”这3种情况&#xff0c;来说…

enote笔记法之附录2——5w1h2k关联词(ver0.22)

enote笔记法之附录2——5w1h2k关联词&#xff08;ver0.22&#xff09; 最上面的是截屏的完整版&#xff0c;分割线下面的是纯文字版本&#xff1a; 作者姓名&#xff08;本人的真实姓名&#xff09;&#xff1a;胡佳吉 居住地&#xff1a;上海 作者网名&#xff1a;EverSt…

【从删库到跑路 | MySQL总结篇】表的增删查改(进阶下)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】&#x1f388; 本专栏旨在分享学习MySQL的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录 一、联合…

【接口技术】实验3:可编程并行接口8255

实验3 可编程并行接口8255实验 一、实验目的 1&#xff1a;了解8255芯片结构及编程方法。 2&#xff1a;了解8255输入/输出实验方法。 3&#xff1a;掌握8255控制键盘及显示电路的基本功能及编程方法。 4&#xff1a;掌握一般键盘和显示电路的工作原理。 二、实验内容 1&…

WS2812灯条基于WLED开源项目无门槛使用简介

WS2812灯条基于WLED开源项目无门槛使用简介 &#x1f4cc;项目github地址&#xff1a;https://github.com/Aircoookie/WLED&#x1f4cd;WLED详情地址&#xff1a;https://kno.wled.ge/&#x1f388;网页在线烧录固件地址&#xff1a;https://install.wled.me/ ✨ 仅作为使用的…

安全技术与防火墙

目录 一、安全技术 1、安全技术 2、防火墙的分类 二、netfilter 1、netfilter简述 2、防火墙工具 1.iptables工具 2.netfilter的四表五链 3.内核中数据包的传输过程 4.三种报文流向 5.实操 总结&#xff1a;本章主要介绍了安全技术与防火墙 一、安全技术 1、安全技…

解决Unable to preventDefault inside passive event listener invocation.报错

报错信息&#xff1a; 这个报错大致说的是&#xff1a;无法在被动事件侦听器调用中防止Default 查了其他博主的解决办法&#xff1a;比如&#xff1a; 1、声明事件监听的时候设置为主动事件监听&#xff1a; window.addEventListener(‘touchmove’, handler, { passive: fal…

【软件测试学习】—软件测试模型(二)

【软件测试学习】—软件测试模型&#xff08;二&#xff09; 我 | 在这里 &#x1f469;‍&#x1f9b0;&#x1f469;‍&#x1f9b0; 读书 | 长沙 ⭐计算机科学与技术 ⭐ 本科 【2024届】 &#x1f383;&#x1f383; 爱好 | 旅游、跑步、网易云、美食、摄影 &#x1f396;️…

VR特警野外武装仿真虚拟训练实操教学保证训练效果

特警VR模拟仿真训练软件的优势主要体现在以下几个方面&#xff1a; 真实感和沉浸感&#xff1a;通过VR技术&#xff0c;特警可以在虚拟环境中体验真实的训练场景&#xff0c;如人质解救、反恐行动等。这种真实感和沉浸感可以帮助特警更好地理解和适应实际情况&#xff0c;提高训…