前言
- Spring 自带的异步调用,方便使用
- Spring 的异步存储在内存中,突然宕机会导致任务丢失,只能执行不重要的操作,比如:日志写入。
- 应用场景:发短信、邮件、消息通知、统计,和正常业务没有直接关联。上下文无关,数据不重要,可以出错。
- 正常业务上下文关联,异步不能出错。后面操作依赖前面操作的结果,需要等待。
步骤
- 参考博客。文章来自大佬博客,我只是实践一下。
- 思维导图。重点内容描述,并发步骤。
- pom依赖。pom依赖文件
- Service 层。用于编写 同步 和 异步方法。
- main 类。
- Test 类。用于测试 同步 和 异步方法。
- application.yml。对配置类的讲解,实际上就是自动装配方案,加上一些描述。
- 学习方法。
- 注意事项。
1. 参考博客
- 芋道 Spring Boot 异步任务入门 https://www.iocoder.cn/Spring-Boot/Async-Job/
2. 思维导图
- 待补充
3. pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jtfr</groupId>
<artifactId>Spring-async</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4. Service 层
5. main 类
package com.jtfr;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class, args);
}
}
6. Test 类
package com.jtfr.service;
import com.jtfr.SpringBootMain;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootMain.class)
public class TestServiceTest {
private static final Logger logger = LoggerFactory.getLogger(TestServiceTest.class);
@Autowired
private TestService testService;
@Test
public void test01(){
long l = System.currentTimeMillis();
logger.info("开始执行");
testService.execute01();
testService.execute02();
logger.info("结束执行,耗时 {} 毫秒", System.currentTimeMillis() - l);
}
@Test
public void test02(){
long l = System.currentTimeMillis();
logger.info("执行开始");
testService.executeAsync01();
testService.executeAsync02();
logger.info("结束执行,耗时 {} 毫秒", System.currentTimeMillis() - l);
}
@Test
public void test03() throws ExecutionException, InterruptedException {
long l = System.currentTimeMillis();
logger.info("执行开始");
Future<Integer> future01 = testService.executeAsyncWithFuture01();
Future<Integer> future02 = testService.executeAsyncWithFuture02();
logger.info(String.valueOf(future01.get()));
logger.info(String.valueOf(future02.get()));
logger.info("结束执行,耗时 {} 毫秒, 等待返回结果", System.currentTimeMillis() - l);
}
}
7. application.yml
spring:
task:
execution:
thread-name-prefix: task-
pool:
core-size: 8
max-size: 20
keep-alive: 60s
queue-capacity: 200
allow-core-thread-timeout: true
shutdown:
await-termination: true
await-termination-period: 60
8. 学习方法
- 百度啊,百度应用案例。
9. 注意事项
- VM 应用的正常优雅关闭,保证异步任务都被执行完成。
- 还没有处理 - 编写异步异常处理器 GlobalAsyncExceptionHandler ,记录异常日志,进行监控告警。