@Async失效之谜
@Async如何使用
- 异步的方法上加上@Async异步注解
- 启动类中需要加上@EnableAsync才有效
使用时类似于下列函数:
new Thread(()-> System.out.println("hello world !"))
@Async线程池
- 默认线程池
无论重复多少次,都默认8个左右的线程在跑
异步线程:task-1执行成功
异步线程:task-2执行成功
异步线程:task-3执行成功
异步线程:task-4执行成功
异步线程:task-5执行成功
异步线程:task-6执行成功
异步线程:task-7执行成功
异步线程:task-1执行成功
异步线程:task-2执行成功
异步线程:task-8执行成功
异步线程:task-3执行成功
异步线程:task-8执行成功
异步线程:task-6执行成功
异步线程:task-8执行成功
异步线程:task-5执行成功
异步线程:task-3执行成功
异步线程:task-2执行成功
异步线程:task-1执行成功 - 自定义线程池配置
/**
* 为Async配置自定义线程池
* 可存放的最多线程数为:MAX_POOL_SIZE+QUEUE_CAPACITY,同时进入线程池的数量超过这个就会报错
* 线程名称最多为MAX_POOL_SIZE个
*/
@Configuration
public class MyTaskExecutorConfig implements AsyncConfigurer {
/**
* 设置ThreadPoolExecutor的核心池大小。
*/
private static final int CORE_POOL_SIZE = 2;
/**
* 设置ThreadPoolExecutor的最大池大小。
*/
private static final int MAX_POOL_SIZE = 3;
/**
* 设置ThreadPoolExecutor的BlockingQueue的容量。
*/
private static final int QUEUE_CAPACITY = 5;
/**
* 配置类实现AsyncConfigurer接口并重写getAsyncExcutor方法,并返回一个ThreadPoolTaskExevutor
* 这样我们就获得了一个基于线程池的TaskExecutor
*/
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
taskExecutor.setQueueCapacity(QUEUE_CAPACITY);
taskExecutor.initialize();
return taskExecutor;
}
}
异步线程:ThreadPoolTaskExecutor-2执行成功
异步线程:ThreadPoolTaskExecutor-1执行成功
异步线程:ThreadPoolTaskExecutor-3执行成功
异步线程:ThreadPoolTaskExecutor-1执行成功
异步线程:ThreadPoolTaskExecutor-3执行成功
异步线程:ThreadPoolTaskExecutor-2执行成功
异步线程:ThreadPoolTaskExecutor-1执行成功
异步线程:ThreadPoolTaskExecutor-3执行成功
@Async和@Controller同时使用存在异常
AbstractHandlerMethodMapping初始bean时,在afterPropertiesSet方法中initHandlerMethods()关联我们的SpringMVCBean
// 类型判断
if (beanType != null && isHandler(beanType)) {
// url处理
detectHandlerMethods(beanName);
}
// Controller和RequestMapping注解判断
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
a、@Controller不使用@Async注解时
@RestController
@Slf4j
public class MemberServiceImpl1 {
@GetMapping("/addUser1")
public String addUser() {
log.info(">>>流程1");
log.info(">>>流程2");
return "success";
}
}
b、@Controller使用@Async注解,但不继承接口时,异步失效
@RestController
@Slf4j
public class MemberServiceImpl3 {
@GetMapping("/addUser3")
public String addUser() {
log.info(">>>流程1");
addUserLog();
log.info(">>>流程3");
return "success";
}
@Async()
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}
c、@Controller使用@Async注解,同时继承接口
@RestController
@Slf4j
public class MemberServiceImpl4 implements MemberService {
@Override
@GetMapping("/addUser4")
public String addUser() {
log.info(">>>流程1");
addUserLog();
log.info(">>>流程3");
return "success";
}
@Async()
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}
@Async使用建议
- a、异步执行的建议单独开启一个类实现,或者从容器中直接获取到该代理类后执行
/**
* 异步代码写到别的地方,不要和Controller注解同时使用
*/
@RestController
@Slf4j
public class ResolveServiceImpl {
@Autowired
private MemberServiceManage memberServiceManage;
@GetMapping("/resolve2")
public String addUser() {
log.info(">>>流程1");
memberServiceManage.addUserLog();
log.info(">>>流程3");
return "success";
}
}
@Component
@Slf4j
public class MemberServiceManage {
@Async
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}
/**
* 使用SpringUtils获得bean后调用,不要使用this操作
*/
@RestController
@Slf4j
public class ResolveServiceImpl {
@GetMapping("/resolve1")
public String addUser() {
log.info(">>>流程1");
//把直接调用改为从容器中取一次
ResolveServiceImpl bean = SpringUtils.getBean(ResolveServiceImpl.class);
bean.addUserLog();
log.info(">>>流程3");
return "success";
}
@Async()
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}
- b、异步的方法上不要加static,加了static就不走AOP了
@Async失效之谜的更多相关文章
- springboot2.0 如何异步操作,@Async失效,无法进入异步
springboot异步操作可以使用@EnableAsync和@Async两个注解,本质就是多线程和动态代理. 一.配置一个线程池 @Configuration @EnableAsync//开启异步 ...
- Spring AOP失效之谜
每天学习一点点 编程PDF电子书免费下载: http://www.shitanlife.com/code 什么是AOP1 AOP(Aspect Oriented Programming),即面向切面编 ...
- Spring aop注解失效
问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...
- SpringBoot线程池的创建、@Async配置步骤及注意事项
最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信.考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看见了Spring的@Async了. 但是 ...
- 关于AOP无法切入同类调用方法的问题
一.前言 Spring AOP在使用过程中需要注意一些问题,也就是平时我们说的陷阱,这些陷阱的出现是由于Spring AOP的实现方式造成的.每一样技术都或多或少有它的局限性,很难称得上完美,只要掌握 ...
- Java开发技术
1.基础技术 数据结构与算法 逻辑结构:数据对象中的数据元素之间的逻辑关系 1.集合结构:集合结构中的数据元素除了同属一个集合外,没有其他关系. 2.线性结构:线性结构中的数据元素之间是一对一的关 ...
- 如何在Spring异步调用中传递上下文
以下文章来源于aoho求索 ,作者aoho 1. 什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步 ...
- 关于Spring注解@Async引发其他注解失效
概述 在前面一篇文章中,介绍,在一个Bean中注入自己,如果有@Async和@Transaction,如果使用@Autowire注入自身,会报循环依赖,如果使用BeanFactoryAware注入自己 ...
- 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考原贴地址:https://blog.csdn.net/clementad/article/details/47339519 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Trans ...
随机推荐
- Linux下如何使用X86 CPU的GPIO
目录 1.前言 2.linux pinctrl子系统 3. pin controller driver 4.手动构造device 1.前言 在arm嵌入式开发中,各个外设具有固定的物理地址,我们可以直 ...
- Java到处运行的基础之 Class 文件
Java 实现一次编译到处运行的基础,来源于 Java 虚拟机屏蔽了操作系统的底层细节.使用 class 文件存储编译后的源程序,使得 Java 程序的编译与操作系统解耦.正是因为 Java clas ...
- Redis常用命令(5)——Set
SADD 格式:SADD key member [member ...] 作用:在集合key中插入一个或多个元素.如果member已经存在,则忽略member.如果key不存在则先创建集合key. 返 ...
- git同步源码到gitee和github
如何把我们的源码同步到gitee或github远程仓库中 同步方式分以下几种: 1.命令同步 先查看下我们是否有远程仓库:git remote -v 如有就要删除远程仓库或是同命令覆盖,如全新安 ...
- Python使用进程制作爬虫
详情点我跳转 关注公众号"轻松学编程"了解更多. 1.进程 1.进程的概念 什么是进程->CPU在同一时刻只能处理一个任务,只是因为cpu执行速度很快. cpu在各个任务之间 ...
- 构建者模式(Builder pattern)
构建者模式应用场景: 主要用来构建一些复杂对象,这里的复杂对象比如说:在建造大楼时,需要先打牢地基,搭建框架,然后自下向上地一层一层盖起来.通常,在建造这种复杂结构的物体时,很难一气呵成.我们需要首先 ...
- Python 列表的11个重要操作
列表是python中内置的数据结构,它的表现形式为方括号中不同数据的集合,用逗号分隔开.列表可以用来存储相同数据类型或不同数据类型. 列表是可变的,这也是它如此常用的原因,然而在某些情况下,可变性需要 ...
- c#反转
string[] arr = Console.ReadLine().Split(' '); string result = string.Empty; for (int i = arr.Count() ...
- Android基础——项目的文件结构(二)
Android基础--项目的文件结构(二) AndroidManifest.xml文件分析 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目 ...
- 腾讯云对象存储COS新品发布——智能分层存储,自动优化您的存储成本
近日,腾讯云正式发布对象存储新品--智能分层存储,能够根据用户数据的访问模式,自动地转换数据的冷热层级,为用户提供与标准存储一致的低延迟和高吞吐的产品体验,同时具有更低的存储成本. 熟悉数据存储的用户 ...