@EnableAsync开启@Async注解功能
一、功能
@Async注解标记的方法可以使该方法异步的进行调用,如果在类上使用该注解,那么这个类的所有方法都会作为异步方法进行调用
注意点,Async注解是基于SpringAop进行实现的,所以在相同的一个类中,方法互相调用是不会起到异步执行的作用的,这里多说一句,任何使用spring aop代理实现的类,类内部方法调用代理肯定是不生效的
1、不需要返回值调用方式
@Component
public class MyTestService {
@Async
public void a() {
System.out.println("a");
}
}
2、指定使用线程池的调用方式,(如果这个线程池在spring容器中不存在则抛出bean找不到的异常)
@Component
public class MyTestService {
@Async("myThreadPoolExecutor")
public void a() {
System.out.println("a");
}
}
3、需要返回值的调用方式
@Component
public class MyTestService {
@Async
public Future<String> a() throws Exception {
return new AsyncResult<String>("a");
}
}
二、关于Async注解线程的使用情况
1、默认情况1
假设当前spring容器中没有任何自定义的线程池,Async注解也没有指定使用哪个线程池,那么默认使用org.springframework.core.task.SimpleAsyncTaskExecutor类,进行异步方法的调用,这个类本身内部并没有线程池的概念,既每次使用都会使用new Thread().start()的方式进行创建和执行。(如果频繁大量的创建线程必然会发生问题... ,实际情况肯定是需要使用线程池的)
2、默认情况2
假设当前spring容器中有自定义的线程池,那么它会使用当前容器中的线程池(注意这里指的有是说容器中只有1个线程池的情况,假如超过1个,那么还是按照默认情况1,进行执行)
3、指定默认使用的线程池,既没有在Async注解中指定使用哪个线程池,替代默认的线程使用规则
实现org.springframework.scheduling.annotation.AsyncConfigurer接口,下面代码是这个接口的描述
public interface AsyncConfigurer {
/**
* The {@link Executor} instance to be used when processing async
* method invocations.
*/
Executor getAsyncExecutor();
/**
* The {@link AsyncUncaughtExceptionHandler} instance to be used
* when an exception is thrown during an asynchronous method execution
* with {@code void} return type.
*/
AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler();
}
第一个方法是获取执行调度的线程池(也就是指定Async注解使用的线程池)
第二个方法是,处理执行过程中发生的异常情况(这里所说的异常情况不包含线程池的rejectedExecution,而是你的业务方法自身抛出的异常)
下面是具体代码配置
@Configuration
public class AsyncPoolConfiguration implements AsyncConfigurer {
@Autowired
private AsyncTaskThreadPool asyncTaskThreadPool;
@Override
public Executor getAsyncExecutor() {
return asyncTaskThreadPool;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}