@EnableAsync开启@Async注解功能
一、功能
@Async注解标记的方法可以使该方法异步的进行调用,如果在类上使用该注解,那么这个类的所有方法都会作为异步方法进行调用
注意点,Async注解是基于SpringAop进行实现的,所以在相同的一个类中,方法互相调用是不会起到异步执行的作用的,这里多说一句,任何使用spring aop代理实现的类,类内部方法调用代理肯定是不生效的
1、不需要返回值调用方式
1@Component 2public class MyTestService { 3 4 @Async 5 public void a() { 6 System.out.println("a"); 7 } 8 9}
2、指定使用线程池的调用方式,(如果这个线程池在spring容器中不存在则抛出bean找不到的异常)
1@Component 2public class MyTestService { 3 4 @Async("myThreadPoolExecutor") 5 public void a() { 6 System.out.println("a"); 7 } 8 9}
3、需要返回值的调用方式
1@Component 2public class MyTestService { 3 4 @Async 5 public Future<String> a() throws Exception { 6 return new AsyncResult<String>("a"); 7 } 8 9}
二、关于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接口,下面代码是这个接口的描述
1public interface AsyncConfigurer { 2 3 /** 4 * The {@link Executor} instance to be used when processing async 5 * method invocations. 6 */ 7 Executor getAsyncExecutor(); 8 9 /** 10 * The {@link AsyncUncaughtExceptionHandler} instance to be used 11 * when an exception is thrown during an asynchronous method execution 12 * with {@code void} return type. 13 */ 14 AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(); 15 16}
第一个方法是获取执行调度的线程池(也就是指定Async注解使用的线程池)
第二个方法是,处理执行过程中发生的异常情况(这里所说的异常情况不包含线程池的rejectedExecution,而是你的业务方法自身抛出的异常)
下面是具体代码配置
1@Configuration 2public class AsyncPoolConfiguration implements AsyncConfigurer { 3 4 @Autowired 5 private AsyncTaskThreadPool asyncTaskThreadPool; 6 7 @Override 8 public Executor getAsyncExecutor() { 9 return asyncTaskThreadPool; 10 } 11 12 @Override 13 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 14 return new SimpleAsyncUncaughtExceptionHandler(); 15 } 16}