@Async异步任务
在日常项目中经常会遇到一些耗时的附加功能,不影响程序主功能。比如说:发送邮件,下载Excel任务之类;如果需要用户在界面等待当前功能执行结束才能继续做接下来的操作,体验感时绝对很差的,这个时候,就需要开启异步任务,让用户无感知的进行操作。
模拟不使用异步任务
- 控制器代码
//test控制器
@RequestMapping("/user")
@RestController
@ResponseBody
public class Controller {
@Autowired
TestService testService;
public void test(){
System.out.println("进入test控制器。。。");
testService.test();
System.out.println("test控制器执行结束");
}
}
- service层测试代码
@Service
public class TestService {
public void test(){
try {
Thread.sleep(3000); //模拟功能需要执行3s时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行test方法");
}
}
- 执行结果:
这种方式,拿发送邮件功能举例,从用户的角度看,必须要邮件发送成功后才能做接下来的操作,这种等待过程肯定是不友好的。。。
@Async异步
- 方法上加异步调用注解
@Async //表明这是个异步调用的任务
public void test(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行test方法");
}
- 启动类开启异步任务
@SpringBootApplication
@EnableAsync//开启异步执行任务
public class InterceptorApplication {
public static void main(String[] args) {
SpringApplication.run(InterceptorApplication.class, args);
}
}
- 执行结果
运行发现,程序并没有等待test方法执行,而是开启异步任务执行test。
注意点
以下情况会导致@Async注解失效:
- 异步方法使用 static 修饰;
- 异步类没有使用 @Component 注解(或其他注解)导致 Spring 无法扫描到异步类;
- 异步方法不能与被调用的异步方法在同一个类中;
- 类中需要使用 @Autowired 或 @Resource 等注解自动注入,不能手动 new 对象;
- 如果使用 Spring Boot 框架必须在启动类中增加 @EnableAsync 注解。