1. Spring реализует асинхронные задачи
Spring предоставляет интерфейс
org.springframework.core.task.TaskExecutor
, этот интерфейс реализуетjava.util.concurrent.Executor
Интерфейс, интерфейс Executor, студенты, знакомые с многопоточностью, должны знать, это интерфейс верхнего уровня пула потоков java, что означает, что TaskExecutor также является пулом потоков и выполняет наши асинхронные задачи через пул потоков.
1. На основе конфигурации xml
Пул потоков TaskExecutor настраивается через XML-файл. Конкретная конфигурация выглядит следующим образом.
<!--
代码中引用即可 @Autowired
id:线程池名称,池中线程的名称前缀 ThreadPoolTaskExecutor
pool-size:单一的值表示核心线程数量,如果是5-25,表示core-max
queue-capacity:队列容量,默认是无界队列,可能会导致OOM,而且在无界队列的情况下,最大线程就无效了,只有固定线程才适合无界队列
rejection-policy:当都满了的时候的拒绝策略,AbortPolice,CallerRunsPolicy,DiscardPolicy,DiscardOldestPolicy
keep-alive:超过核心线程数量的线程的保活时间,如果设置为0,表示任务执行完之后立即回收 单位:s
-->
<task:executor id="myExecutor"
pool-size="5-25"
queue-capacity="200"
rejection-policy="ABORT"
keep-alive="120"/>
Из приведенной выше конфигурации видно, что на самом деле это обычная конфигурация пула потоков.
Как использовать:
public class MyAsync {
/**
* 注入线程池
*/
@Autowired
private TaskExecutor taskExecutor;
/**
* 无返回值、无参数
*/
public void async() {
// taskExecutor.execute(new MyTask());
}
/**
* 有参数、无返回值
*
* @param param
*/
public void param(String param) {
// taskExecutor.execute(new MyTask());
}
/**
* Future 异步返回
*
* @return
*/
public Future<String> future() {
// taskExecutor.execute(new MyTask());
return new AsyncResult<String>("result");
}
/**
* CompletableFuture 异步返回
*
* @return
*/
public CompletableFuture<String> completedFuture() {
// taskExecutor.execute(new MyTask());
return CompletableFuture.completedFuture("result");
}
}
На основе конфигурации xml его также можно настроить для включения@Async
Обратите внимание, что конкретная конфигурация выглядит следующим образом:
<!--
该标签是用于开启注解模式的,识别@Scheduled
executor:executor bean name
scheduler:scheduler bean name
exception-handler:ThreadPoolTaskExecutor exception handler bean name
mode:代理方式 1.AspectJ 2.JDK Proxy 默认JDK Proxy
proxy-target-class:是否代理目标类 默认false
-->
<task:annotation-driven executor="myExecutor"/>
Использовать напрямую@Async
Аннотацию можно использовать следующим образом:
public class MyAsync {
/**
* 无返回值、无参数
*/
@Async
public void async() {
}
/**
* 有参数、无返回值
*
* @param param
*/
@Async
public void param(String param) {
}
/**
* Future 异步返回
*
* @return
*/
@Async
public Future<String> future() {
return new AsyncResult<String>("result");
}
/**
* CompletableFuture 异步返回
*
* @return
*/
@Async
public CompletableFuture<String> completedFuture() {
return CompletableFuture.completedFuture("result");
}
}
2. На основе конфигурации Java
Конфигурация на основе конфигурации Java должна быть реализованаorg.springframework.scheduling.annotation.AsyncConfigurer
Интерфейс, конкретный код выглядит следующим образом.
@Configuration
public class MyAsyncConfigure implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.execute(myTask());
Future<?> future = executor.submit(myTask());
return executor;
}
/**
* 异常处理
*
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
public MyTask myTask() {
return new MyTask();
}
}
3. Аннотация на основе
Конфигурация на основе аннотаций выполняется с помощью@EnableAsync
а также@Asyc
две аннотации
@Configuration
@EnableAsync //开启异步,相当于TaskExecutor
public class MyConfiguration {
/**
* 配置线程池
* 如果不配置,@EnableAsync默认core-size=1
*
* @return
*/
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor scheduler = new ThreadPoolTaskExecutor();
scheduler.setCorePoolSize(10);
return scheduler;
}
}
Как использовать:
public class MyAsync {
/**
* 无返回值、无参数
*/
@Async
public void async() {
}
/**
* 有参数、无返回值
*
* @param param
*/
@Async
public void param(String param) {
}
/**
* Future 异步返回
*
* @return
*/
@Async
public Future<String> future() {
return new AsyncResult<String>("result");
}
/**
* CompletableFuture 异步返回
*
* @return
*/
@Async
public CompletableFuture<String> completedFuture() {
return CompletableFuture.completedFuture("result");
}
}
4. Обработка исключений
1.xml и аннотации
Если вы используете конфигурацию xml или конфигурацию аннотаций, необходимо реализовать обработку исключений.org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
интерфейс, который имеет простую реализациюorg.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler
, эта реализация записывает журнал исключений, мы также можем реализовать этот интерфейс для настройки обработки исключений.
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
}
}
xml использовать:
<!--异常处理-->
<bean id="myAsyncUncaughtExceptionHandler" class="com.ly.task.async.MyAsyncUncaughtExceptionHandler"/>
<task:annotation-driven executor="myExecutor"
exception-handler="myAsyncUncaughtExceptionHandler"/>
Пока метод аннотации настроен, он будет автоматически вызываться при возникновении исключения.
2.java config
В конфигурации java-конфига выше мы реализовалиorg.springframework.scheduling.annotation.AsyncConfigurer
интерфейс для настройки, этот интерфейс имеетorg.springframework.scheduling.annotation.AsyncConfigurer#getAsyncUncaughtExceptionHandler
метод, вы можете напрямую обрабатывать исключения в этом методе.