@Async异步注解与SpringBoot结合使用
当你在service层需要启动异步线程去执行某些分支任务,又不希望显式使用Thread等线程相关类,只想专注于实现业务逻辑代码开发,可以使用@Async异步注解。
1、 使用@Async 异步注解
Controller层方法:
//批量插入用户
@RequestMapping("/user/addSystemUser")
public void batchAddUser(@RequestParam(value = "usernameList[]",required=false) List usernameList){
for (int i = 0; i < usernameList.size(); i++) {
//使用异步线程执行每一个用户新增
userService.addUser(usernameList.get(i));
}
}
Service层方法,是真正使用@Async异步注解的:
@Transactional(propagation = Propagation.NESTED) //如果当前事务存在,则在嵌套事务中执行。如果没有,就新建一个事务;
@Async
public void addUser(SystemUser sessionUser, List<Container> containerList, Timestamp createTime){
// do save one User
}
2、@Async异步注解使用注意点
a)该注解可使用在类、接口(包括注释类型)或枚举声明
b)当被标注在方法级别时,该方法返回值要么是void,或java.util.concurrent.Future接口实现类
3、自定义异步注解真正的执行线程类(可选)
如果懒得自己写一个线程执行类的话,我猜SpringBoot会默认设置一些org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor类的配置。
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 创建自定义配置的线程池
*/
@Configuration
@EnableAsync
public class MyTaskExecutePool implements AsyncConfigurer {
private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(ASyncTask.class);
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(20);
//最大线程数
executor.setMaxPoolSize(40);
//队列容量
executor.setQueueCapacity(50);
//活跃时间
executor.setKeepAliveSeconds(30);
//线程名字前缀
executor.setThreadNamePrefix("MyTaskExecutePool-");
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
/**
* 异步任务中异常处理
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {
//纪录log错误日志
LOG.error("exception method:"+arg1.getName()+";"+arg0.getMessage(), arg0);
}
};
}
}
4、日志监控异步线程活动(可选)
logback.xml配置文件中设置 %thread 纪录线程执行名
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 级别过滤器。如果日志级别低于WARN,将被过滤掉。 ALL TRACE DEBUG INFO WARN ERROR-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %msg - %file:%line%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
@Async异步注解与SpringBoot结合使用的更多相关文章
- spring boot使用@Async异步注解
1.java的大部分接口的方法都是串行执行的,但是有些业务场景是不需要同步返回结果的,可以把结果直接返回,具体业务异步执行,也有些业务接口是需要并行获取数据,最后把数据聚合在统一返回给前端. 通常我们 ...
- async异步注解和aspect切面注解等注解的原理
在我们使用spring框架的过程中,在很多时候我们会使用@async注解来异步执行某一些方法,提高系统的执行效率.今天我们来探讨下spring是如何完成这个功能的. 1.spring 在扫描bean的 ...
- spring boot @Async异步注解上下文透传
上一篇文章说到,之前使用了@Async注解,子线程无法获取到上下文信息,导致流量无法打到灰度,然后改成 线程池的方式,每次调用异步调用的时候都手动透传 上下文(硬编码)解决了问题. 后面查阅了资料,找 ...
- 关于Dubbo和Spring异步注解@Async的冲突
项目中难免会有异步处理的需求,像异步记录日志啦,异步发送邮件啦,而Dubbo又是现在主流的分布式框架,所有异步+Dubbo的组合是再所难免的 但博主是实践中发现Dubbo的服务并不能很好的跟Sprin ...
- springboot:使用异步注解@Async的那些坑
springboot:使用异步注解@Async的那些坑 一.引言 在java后端开发中经常会碰到处理多个任务的情况,比如一个方法中要调用多个请求,然后把多个请求的结果合并后统一返回,一般情况下调用其他 ...
- springboot:嵌套使用异步注解@Async还会异步执行吗
一.引言 在前边的文章<[springboot:使用异步注解@Async的那些坑>中介绍了使用@Async注解获取任务执行结果的错误用法,今天来分享下另外一种常见的错误. 二.代码演示 下 ...
- springboot:使用异步注解@Async的前世今生
在前边的文章中,和小伙伴一起认识了异步执行的好处,以及如何进行异步开发,对,就是使用@Async注解,在使用异步注解@Async的过程中也存在一些坑,不过通过正确的打开方式也可以很好的避免,今天想和大 ...
- SpringBoot @Async 异步处理业务逻辑和发短信逻辑
有个业务场景,业务数据审核通过后需要给用户发短信,发短信过程比较耗时,可能需要几秒甚至十几秒,因此使用异步发短信 使用了注解@Async来实现: 1.SpringApplication启用注解@Ena ...
- Spring中异步注解@Async的使用、原理及使用时可能导致的问题
前言 其实最近都在研究事务相关的内容,之所以写这么一篇文章是因为前面写了一篇关于循环依赖的文章: <面试必杀技,讲一讲Spring中的循环依赖> 然后,很多同学碰到了下面这个问题,添加了S ...
随机推荐
- 未能加载文件或程序集“BLL”或它的某一个依赖项。生成此程序集的运行时比当前加载的运行时新,无法加载此程序集。
今天使用VS2012创建项目的时候,考虑到项目中代码的重用性以及清晰简洁性,搭建了一个三层架构,但是在项目运行的时候,总是报错: “未能加载文件或程序集“BLL”或它的某一个依赖项.生成此程序集的运行 ...
- mysql5.5.28在Linux下的安装
1. 下载mysql 在http://dev.mysql.com/downloads/mysql/ 官网上下载mysql-5.5.28-linux2.6-i686.tar.gz. 2. ...
- Windows 下Redis的部署 及key 过期事件
window下Redis部署,下载安装完成之后,进入到redis目录: 1.修改配置文件redis.windows.service.conf配置密码 requirepass myRedis (注意在R ...
- maven 包下载地址
<groupId>cn.com.bmsoft.smartcity</groupId><artifactId>base</artifactId><p ...
- Selenium之table操作
操作内容: 获取table总行数.总列数.获取某单元格的text值,删除一行[如果每行后边提供删除的按钮] HTML代码: <html><head><meta http- ...
- 如何找出当前活动桌面背景图像的位置/路径(Ubuntu 18.04,GNOME)?
启动终端并运行以下命令 $ gsettings get org.gnome.desktop.background picture-uri 显示当前设置为桌面背景图片的完整路径.
- C#经典面试题及答案
1.请你说说.net 中类和结构的区别? 答:结构和类具有大体的语法,但是结构受到的限制比类多.结构不能声明默认的的构造函数,为结构的副本是编译器创建和销毁的,所以不需要默认的构造函数和析构函数,结构 ...
- docker安装mysql容器后,是用navicat连接报client does not support authentication protocol requested by server consider upgrading mysql client
#进入容器 docker exec -it mysql bash#进入mysqlmysql -u root -p#重置密码ALTER USER 'root'@'%' IDENTIFIED WITH m ...
- 关于ubuntu远程访问服务器的知识点
为了可以打开图形界面,用ssh -X 用户名@地址 如何远程打开文件夹可视化界面 nautilus /文件夹
- Oracle数据库 基础SQL语句练习
一.说明 第一次使用Oracle,想做一些练习,熟悉一些oracle. 表:使用的是scott用户,默认的表 具体表讲解,可以参考该文档:https://www.cnblogs.com/xjcheng ...