1. 简介
在spring中 存在着一个AsyncConfigurer 接口,它是一个可以配置异步线程池的接口,
源码如下:
public interface AsyncConfigurer {
// 获取线程池
@org.springframework.lang.Nullable
default java.util.concurrent.Executor getAsyncExecutor() { /* compiled code */ }
// 异步异常处理器
@org.springframework.lang.Nullable
default org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { /* compiled code */ }
}
getAsyncExecutor 返回的自定义线程池,这样在开启异步时,线程池会提供空闲
线程来执行异步任务。
getAsyncUncaughtExceptionHandler: 异常处理器。
因此只需要java配置文件,实现AsyncConfigurer 接口,实现getAsysncExecutor
方法返回的线程池,这样spring就会使用这个线程池作为异步调用的线程。
为了使异步可用,spring还提供@EnableAsync,如果java配置文件标注它,那么spring
会开启异步可用,这样就可使用@Async 驱动spring 使用异步调用。
示例:
1. 使用Java配置定义线程池,和启动异步。
package com.chenyun.config;
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.util.concurrent.Executor;
/**
* 在代码中,注解@EnableAsyanc代表开启spring异步,这样可以使用@async驱动spring使用异步
* 但异步需要提供可用线程池,所以这里配置类会实现AsyncConfigurer接口,然后覆盖
* getAsyncExecutor方法,这样就可以自定义一个线程池。因此当方法标注@Async时,
* spring就会通过这个线程池的空闲线程去运行该方法。
* */
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
//定义线程池
@Override
public Executor getAsyncExecutor(){
// 定义线程池
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 核心线程数
taskExecutor.setCorePoolSize(100);
// 线程池最大线程数
taskExecutor.setMaxPoolSize(300);
//线程队列最大线程数
taskExecutor.setQueueCapacity(2000);
// 初始化
taskExecutor.initialize();
return taskExecutor;
}
}
2. 异步接口
package com.chenyun.service;
public interface AsyncService {
public void generateReport();
}
3 . 异步方法实现
package com.chenyun.service.impl;
import com.chenyun.service.AsyncService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncServiceImpl implements AsyncService {
@Override
@Async // 声明使用异步调用
public void generateReport(){
//打印异步线程的名称
System.out.println("报表县城名称:"+Thread.currentThread().getName());
}
}
4. 异步控制器
package com.chenyun.web;
import com.chenyun.service.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AsyncController {
@Autowired
private AsyncService asyncService;
@RequestMapping("/async")
public void generateReport(){
System.out.println("请求线程的名称:"+ Thread.currentThread().getName());
asyncService.generateReport();
}
}