Spring中@Async异步操作
一、使用,基于Maven工程
1.1、pom.xml
没有特殊的依赖,common里面也就lombok,guava等基础包
<dependencies>
<dependency>
<groupId>com.tonels</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter-web.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.2、定义异步操作,配置,两个文件
异步配置
@Configuration
@EnableAsync
public class AsyncConfiguration
{
@Bean(name = "asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(3);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsynchThread-");
executor.initialize();
return executor;
}
}
异步操作
@Service
public class AsyncService {
private static Logger log = LoggerFactory.getLogger(AsyncService.class);
@Autowired
private RestTemplate restTemplate;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Async("asyncExecutor")
public CompletableFuture<EmployeeNames> getEmployeeName() throws InterruptedException {
log.info("获取名字 Starts");
EmployeeNames employeeNameData = restTemplate.getForObject("http://localhost:1210/names", EmployeeNames.class);
log.info("employeeNameData, {}", employeeNameData);
Thread.sleep(1000L); // 延迟 1 秒
log.info("获取名字 结束");
return CompletableFuture.completedFuture(employeeNameData);
}
@Async("asyncExecutor")
public CompletableFuture<EmployeeAddresses> getEmployeeAddress() throws InterruptedException {
log.info("获取地址 Starts");
EmployeeAddresses employeeAddressData = restTemplate.getForObject("http://localhost:1210/addresses", EmployeeAddresses.class);
log.info("地址数据, {}", employeeAddressData);
Thread.sleep(1000L); // 延迟一秒
log.info("获取地址 结束");
return CompletableFuture.completedFuture(employeeAddressData);
}
@Async("asyncExecutor")
public CompletableFuture<EmployeePhone> getEmployeePhone() throws InterruptedException {
log.info("获取电话 Starts");
EmployeePhone employeePhoneData = restTemplate.getForObject("http://localhost:1210/phones", EmployeePhone.class);
log.info("电话数据, {}", employeePhoneData);
Thread.sleep(1000L); // 延迟一秒
log.info("获取电话 结束");
return CompletableFuture.completedFuture(employeePhoneData);
}
}
1.3、测试Controller,两个文件
-
EmployeeDataController ,一般的接口Controller定义,根据需要,定义在异步操作中
-
AsyncController ,用于测试异步接口操作的
-
EmployeeDataController
@RestController
public class EmployeeDataController {
private static Logger log = LoggerFactory.getLogger(EmployeeDataController.class);
@GetMapping(value = "/addresses")
public EmployeeAddresses getAddresses() {
EmployeeAddresses employeeAddressesList = new EmployeeAddresses();
EmployeeAddress e1 = new EmployeeAddress().setHouseNo("1111").setStreetNo("111").setZipCode("111111");
EmployeeAddress e2 = new EmployeeAddress().setHouseNo("1111").setStreetNo("111").setZipCode("111111");
ArrayList<EmployeeAddress> list = Lists.newArrayList(e1, e2);
employeeAddressesList.setEmployeeAddressList(list);
return employeeAddressesList;
}
@GetMapping(value = "/phones")
public EmployeePhone getPhoneNumbers() {
EmployeePhone employeePhone = new EmployeePhone();
ArrayList<String> list = Lists.newArrayList("100000", "200000");
employeePhone.setPhoneNumbers(list);
return employeePhone;
}
@GetMapping(value = "/names")
public EmployeeNames getEmployeeName() {
EmployeeNames employeeNamesList = new EmployeeNames();
EmployeeName e1 = new EmployeeName().setFirstName("zhang").setLastName("san");
EmployeeName e2 = new EmployeeName().setFirstName("wang").setLastName("yi");
List<EmployeeName> list = Lists.newArrayList(e1, e2);
employeeNamesList.setEmployeeNameList(list);
// int a = 5/0;
return employeeNamesList;
}
@GetMapping("/trade")
public void t1(Trade trade) {
System.out.println(trade.getAmount());
System.out.println(trade.getTradeDate());
}
}
- AsyncController
@RestController
public class AsyncController {
private static Logger log = LoggerFactory.getLogger(AsyncController.class);
@Autowired
private AsyncService service;
@GetMapping("/testAsynch")
public void testAsynch() throws InterruptedException, ExecutionException {
log.info("测试开始");
CompletableFuture<EmployeeAddresses> employeeAddress = service.getEmployeeAddress();
CompletableFuture<EmployeeNames> employeeName = service.getEmployeeName();
CompletableFuture<EmployeePhone> employeePhone = service.getEmployeePhone();
CompletableFuture.allOf(employeeAddress, employeeName, employeePhone).join();
log.info("雇员地址--> " + employeeAddress.get());
log.info("雇员名字--> " + employeeName.get());
log.info("雇员电话--> " + employeePhone.get());
}
}
还有Model的定义,不是很重要,主要是流程的测试
1.4、启动
@SpringBootApplication
public class SpringBootAsyncApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAsyncApplication.class, args);
}
}
1.5、测试
项目启动后,访问localhost:8080/testAsynch,可发现三个接口是异步同时调用的,