前言 Spring中用@Async注解标记的方法,称为异步方法,它会在调用方的当前线程之外的独立的线程中执行,其实就相当于我们自己new Thread(()-> System.out.println(“hello world !”))这样在另一个线程中去执行相应的业务逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // @Async 若把注解放在类上或者接口上,那么他所有的方法都会异步执行了~~~~(包括私有方法) public interface HelloService { Object hello(); } @Service public class HelloServiceImpl implements HelloService { @Async // 注意此处加上了此注解 @Override public Object hello() { System.out.println("当前线程:" + Thread.currentThread().getName()); return "service hello"; } }
然后只需要在配置里,开启对异步的支持即可:
1 2 3 4 5 @Configuration @EnableAsync // 开启异步注解的支持 public class RootConfig { }
使用的是线程池SimpleAsyncTaskExecutor,这也是Spring默认给我们提供的线程池。
@Async注解使用细节
@Async注解一般用在方法上,如果用在类上,那么这个类所有的方法都是异步执行的;
@Async可以放在任何方法上,即使是private的;
所使用的@Async注解方法的类对象应该是Spring容器管理的bean对象;
@Async可以放在接口处(或者接口方法上)。但是只有使用的是JDK的动态代理时才有效,CGLIB会失效。因此建议:统一写在实现类的方法上;
需要注解@EnableAsync来开启异步注解的支持;
若你希望得到异步调用的返回值,请你的返回值用Futrue变量包装起来
@EnableAsync 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AsyncConfigurationSelector.class) public @interface EnableAsync { Class<? extends Annotation > annotation() default Annotation.class; boolean proxyTargetClass () default false ; AdviceMode mode () default AdviceMode.PROXY; int order () default Ordered.LOWEST_PRECEDENCE; }
1 2 3 4 5 6 7 8 9 10 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Async { String value () default "" ; }
最重要的,还是上面的@Import注解导入的类:AsyncConfigurationSelector
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> { // 这类 我也不知道在哪?是用于支持AspectJ这种静态代理Mode的,忽略吧~~~~ private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME = "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"; @Override @Nullable public String[] selectImports(AdviceMode adviceMode) { // 这里AdviceMode 进行不同的处理,从而向Spring容器注入了不同的Bean~~~ switch (adviceMode) { // 大多数情况下都走这里,ProxyAsyncConfiguration会被注入到Bean容器里面~~~ case PROXY: return new String[] { ProxyAsyncConfiguration.class.getName() }; case ASPECTJ: return new String[] { ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME }; default: return null; } } }
它的作用:抽象实现支持了AdviceMode,并且支持通用的@EnableXXX模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public abstract class AdviceModeImportSelector <A extends Annotation > implements ImportSelector { public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode" ; protected String getAdviceModeAttributeName () { return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME; } @Override public final String[] selectImports(AnnotationMetadata importingClassMetadata) { Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class); Assert.state(annType != null , "Unresolvable type argument for AdviceModeImportSelector" ); AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType); if (attributes == null ) { throw new IllegalArgumentException (String.format( "@%s is not present annType.getSimpleName(), importingClassMetadata.getClassName())); } // 拿到AdviceMode,最终交给子类,让它自己去实现,决定导入哪个Bean AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName()); String[] imports = selectImports(adviceMode); if (imports == null) { throw new IllegalArgumentException(String.format(" Unknown AdviceMode: '%s' ", adviceMode)); } return imports; } // 子类去实现 具体导入哪个Bean @Nullable protected abstract String[] selectImports(AdviceMode adviceMode); }
@EnableAsync最终是向容器内注入了ProxyAsyncConfiguration这个Bean。由名字可议看出,它是一个配置类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration { @Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public AsyncAnnotationBeanPostProcessor asyncAdvisor () { Assert.notNull(this .enableAsync, "@EnableAsync annotation metadata was not injected" ); AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor (); Class<? extends Annotation > customAsyncAnnotation = this .enableAsync.getClass("annotation" ); if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation" )) { bpp.setAsyncAnnotationType(customAsyncAnnotation); } if (this .executor != null ) { bpp.setExecutor(this .executor); } if (this .exceptionHandler != null ) { bpp.setExceptionHandler(this .exceptionHandler); } bpp.setProxyTargetClass(this .enableAsync.getBoolean("proxyTargetClass" )); bpp.setOrder(this .enableAsync.<Integer>getNumber("order" )); return bpp; } }
ProxyAsyncConfiguration的父类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Configuration public abstract class AbstractAsyncConfiguration implements ImportAware { protected AnnotationAttributes enableAsync; protected Executor executor; protected AsyncUncaughtExceptionHandler exceptionHandler; @Override public void setImportMetadata (AnnotationMetadata importMetadata) { this .enableAsync = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false )); if (this .enableAsync == null ) { throw new IllegalArgumentException ("@EnableAsync is not present on importing class " + importMetadata.getClassName()); } } @Autowired(required = false) void setConfigurers (Collection<AsyncConfigurer> configurers) { if (CollectionUtils.isEmpty(configurers)) { return ; } if (configurers.size() > 1 ) { throw new IllegalStateException ("Only one AsyncConfigurer may exist" ); } AsyncConfigurer configurer = configurers.iterator().next(); this .executor = configurer.getAsyncExecutor(); this .exceptionHandler = configurer.getAsyncUncaughtExceptionHandler(); } }
从上可知,真正做文章的最终还是 AsyncAnnotationBeanPostProcessor 这个后置处理器,继承自AbstractAdvisingBeanPostProcessor,从这个名字也能看出来。它主要处理AdvisingBean,也就是处理Advisor和Bean的关系的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor { @Nullable protected Advisor advisor; protected boolean beforeExistingAdvisors = false ; private final Map<Class<?>, Boolean> eligibleBeans = new ConcurrentHashMap <>(256 ); public void setBeforeExistingAdvisors (boolean beforeExistingAdvisors) { this .beforeExistingAdvisors = beforeExistingAdvisors; } @Override public Object postProcessBeforeInitialization (Object bean, String beanName) { return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) { if (bean instanceof AopInfrastructureBean || this .advisor == null ) { return bean; } if (bean instanceof Advised) { Advised advised = (Advised) bean; if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) { if (this .beforeExistingAdvisors) { advised.addAdvisor(0 , this .advisor); } else { advised.addAdvisor(this .advisor); } return bean; } } if (isEligible(bean, beanName)) { ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName); if (!proxyFactory.isProxyTargetClass()) { evaluateProxyInterfaces(bean.getClass(), proxyFactory); } proxyFactory.addAdvisor(this .advisor); customizeProxyFactory(proxyFactory); return proxyFactory.getProxy(getProxyClassLoader()); } return bean; } protected boolean isEligible (Object bean, String beanName) { return isEligible(bean.getClass()); } protected boolean isEligible (Class<?> targetClass) { Boolean eligible = this .eligibleBeans.get(targetClass); if (eligible != null ) { return eligible; } if (this .advisor == null ) { return false ; } eligible = AopUtils.canApply(this .advisor, targetClass); this .eligibleBeans.put(targetClass, eligible); return eligible; } protected ProxyFactory prepareProxyFactory (Object bean, String beanName) { ProxyFactory proxyFactory = new ProxyFactory (); proxyFactory.copyFrom(this ); proxyFactory.setTarget(bean); return proxyFactory; } protected void customizeProxyFactory (ProxyFactory proxyFactory) { } }
AbstractBeanFactoryAwareAdvisingPostProcessor从名字可以看出,它相较于父类,就和BeanFactory有关了,也就是和Bean容器相关了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public abstract class AbstractBeanFactoryAwareAdvisingPostProcessor extends AbstractAdvisingBeanPostProcessor implements BeanFactoryAware { @Nullable private ConfigurableListableBeanFactory beanFactory; @Override public void setBeanFactory (BeanFactory beanFactory) { this .beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory ? (ConfigurableListableBeanFactory) beanFactory : null ); } @Override protected ProxyFactory prepareProxyFactory (Object bean, String beanName) { if (this .beanFactory != null ) { AutoProxyUtils.exposeTargetClass(this .beanFactory, beanName, bean.getClass()); } ProxyFactory proxyFactory = super .prepareProxyFactory(bean, beanName); if (!proxyFactory.isProxyTargetClass() && this .beanFactory != null && AutoProxyUtils.shouldProxyTargetClass(this .beanFactory, beanName)) { proxyFactory.setProxyTargetClass(true ); } return proxyFactory; } }
下面就可以看看具体的两个实现类了: AsyncAnnotationBeanPostProcessor,该实现类就是具体和@Async相关的一个类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor { public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME = AnnotationAsyncExecutionInterceptor.DEFAULT_TASK_EXECUTOR_BEAN_NAME; @Nullable private Class<? extends Annotation > asyncAnnotationType; @Nullable private Executor executor; @Nullable private AsyncUncaughtExceptionHandler exceptionHandler; public AsyncAnnotationBeanPostProcessor () { setBeforeExistingAdvisors(true ); } public void setAsyncAnnotationType (Class<? extends Annotation> asyncAnnotationType) { Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null" ); this .asyncAnnotationType = asyncAnnotationType; } public void setExecutor (Executor executor) { this .executor = executor; } public void setExceptionHandler (AsyncUncaughtExceptionHandler exceptionHandler) { this .exceptionHandler = exceptionHandler; } @Override public void setBeanFactory (BeanFactory beanFactory) { super .setBeanFactory(beanFactory); AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor (this .executor, this .exceptionHandler); if (this .asyncAnnotationType != null ) { advisor.setAsyncAnnotationType(this .asyncAnnotationType); } advisor.setBeanFactory(beanFactory); this .advisor = advisor; } }
AsyncAnnotationAdvisor:可以看出,它是一个PointcutAdvisor,并且Pointcut是一个AnnotationMatchingPointcut,因此是为注解来匹配的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware { private AsyncUncaughtExceptionHandler exceptionHandler; private Advice advice; private Pointcut pointcut; public AsyncAnnotationAdvisor () { this (null , null ); } @SuppressWarnings("unchecked") public AsyncAnnotationAdvisor (@Nullable Executor executor, @Nullable AsyncUncaughtExceptionHandler exceptionHandler) { Set<Class<? extends Annotation >> asyncAnnotationTypes = new LinkedHashSet <>(2 ); asyncAnnotationTypes.add(Async.class); try { asyncAnnotationTypes.add((Class<? extends Annotation >) ClassUtils.forName("javax.ejb.Asynchronous" , AsyncAnnotationAdvisor.class.getClassLoader())); } catch (ClassNotFoundException ex) { } if (exceptionHandler != null ) { this .exceptionHandler = exceptionHandler; } else { this .exceptionHandler = new SimpleAsyncUncaughtExceptionHandler (); } this .advice = buildAdvice(executor, this .exceptionHandler); this .pointcut = buildPointcut(asyncAnnotationTypes); } public void setTaskExecutor (Executor executor) { this .advice = buildAdvice(executor, this .exceptionHandler); } public void setAsyncAnnotationType (Class<? extends Annotation> asyncAnnotationType) { Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null" ); Set<Class<? extends Annotation >> asyncAnnotationTypes = new HashSet <>(); asyncAnnotationTypes.add(asyncAnnotationType); this .pointcut = buildPointcut(asyncAnnotationTypes); } @Override public void setBeanFactory (BeanFactory beanFactory) { if (this .advice instanceof BeanFactoryAware) { ((BeanFactoryAware) this .advice).setBeanFactory(beanFactory); } } @Override public Advice getAdvice () { return this .advice; } @Override public Pointcut getPointcut () { return this .pointcut; } protected Advice buildAdvice (@Nullable Executor executor, AsyncUncaughtExceptionHandler exceptionHandler) { return new AnnotationAsyncExecutionInterceptor (executor, exceptionHandler); } protected Pointcut buildPointcut (Set<Class<? extends Annotation>> asyncAnnotationTypes) { ComposablePointcut result = null ; for (Class<? extends Annotation > asyncAnnotationType : asyncAnnotationTypes) { Pointcut cpc = new AnnotationMatchingPointcut (asyncAnnotationType, true ); Pointcut mpc = new AnnotationMatchingPointcut (null , asyncAnnotationType, true ); if (result == null ) { result = new ComposablePointcut (cpc); } else { result.union(cpc); } result = result.union(mpc); } return (result != null ? result : Pointcut.TRUE); } }
从上的源码可议看出,默认是支持@Asycn以及EJB的那个异步注解的。但是最终的增强行为,委托给了AnnotationAsyncExecutionInterceptor。AnnotationAsyncExecutionInterceptor是一个MethodInterceptor,并且继承自AsyncExecutionAspectSupport。 AsyncExecutionAspectSupport从类名就可以看出,它是用来支持处理异步线程执行器的,若没有指定,靠它提供一个默认的异步执行器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor" ; private final Map<Method, AsyncTaskExecutor> executors = new ConcurrentHashMap <>(16 ); @Nullable private volatile Executor defaultExecutor; private AsyncUncaughtExceptionHandler exceptionHandler; @Nullable private BeanFactory beanFactory; public AsyncExecutionAspectSupport (@Nullable Executor defaultExecutor) { this (defaultExecutor, new SimpleAsyncUncaughtExceptionHandler ()); } public AsyncExecutionAspectSupport (@Nullable Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) { this .defaultExecutor = defaultExecutor; this .exceptionHandler = exceptionHandler; } public void setExecutor (Executor defaultExecutor) { this .defaultExecutor = defaultExecutor; } public void setExceptionHandler (AsyncUncaughtExceptionHandler exceptionHandler) { this .exceptionHandler = exceptionHandler; } @Override public void setBeanFactory (BeanFactory beanFactory) { this .beanFactory = beanFactory; } @Nullable protected AsyncTaskExecutor determineAsyncExecutor (Method method) { AsyncTaskExecutor executor = this .executors.get(method); if (executor == null ) { Executor targetExecutor; String qualifier = getExecutorQualifier(method); if (StringUtils.hasLength(qualifier)) { targetExecutor = findQualifiedExecutor(this .beanFactory, qualifier); } else { targetExecutor = this .defaultExecutor; if (targetExecutor == null ) { synchronized (this .executors) { if (this .defaultExecutor == null ) { this .defaultExecutor = getDefaultExecutor(this .beanFactory); } targetExecutor = this .defaultExecutor; } } } if (targetExecutor == null ) { return null ; } executor = (targetExecutor instanceof AsyncListenableTaskExecutor ? (AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter (targetExecutor)); this .executors.put(method, executor); } return executor; } @Nullable protected abstract String getExecutorQualifier (Method method) ; @Nullable protected Executor findQualifiedExecutor (@Nullable BeanFactory beanFactory, String qualifier) { if (beanFactory == null ) { throw new IllegalStateException ("BeanFactory must be set on " + getClass().getSimpleName() + " to access qualified executor '" + qualifier + "'" ); } return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier); } @Nullable protected Executor getDefaultExecutor (@Nullable BeanFactory beanFactory) { if (beanFactory != null ) { try { return beanFactory.getBean(TaskExecutor.class); } catch (NoUniqueBeanDefinitionException ex) { try { return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class); } catch (NoSuchBeanDefinitionException ex2) { } } catch (NoSuchBeanDefinitionException ex) { try { return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class); } catch (NoSuchBeanDefinitionException ex2) { } } } return null ; } @Nullable protected Object doSubmit (Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) { if (CompletableFuture.class.isAssignableFrom(returnType)) { return CompletableFuture.supplyAsync(() -> { try { return task.call(); } catch (Throwable ex) { throw new CompletionException (ex); } }, executor); } else if (ListenableFuture.class.isAssignableFrom(returnType)) { return ((AsyncListenableTaskExecutor) executor).submitListenable(task); } else if (Future.class.isAssignableFrom(returnType)) { return executor.submit(task); } else { executor.submit(task); return null ; } } protected void handleError (Throwable ex, Method method, Object... params) throws Exception { if (Future.class.isAssignableFrom(method.getReturnType())) { ReflectionUtils.rethrowException(ex); } else { try { this .exceptionHandler.handleUncaughtException(ex, method, params); } catch (Throwable ex2) { logger.error("Exception handler for async method '" + method.toGenericString() + "' threw unexpected exception itself" , ex2); } } } }
这个类相当于已经做了大部分的工作了,接下来继续看子类:AsyncExecutionInterceptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor , Ordered { ... @Override @Nullable protected String getExecutorQualifier (Method method) { return null ; } @Override @Nullable protected Executor getDefaultExecutor (@Nullable BeanFactory beanFactory) { Executor defaultExecutor = super .getDefaultExecutor(beanFactory); return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor ()); } @Override public int getOrder () { return Ordered.HIGHEST_PRECEDENCE; } @Override @Nullable public Object invoke (final MethodInvocation invocation) throws Throwable { Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null ); Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass); final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod); if (executor == null ) { throw new IllegalStateException ( "No executor specified and no default executor set on AsyncExecutionInterceptor either" ); } Callable<Object> task = () -> { try { Object result = invocation.proceed(); if (result instanceof Future) { return ((Future<?>) result).get(); } } catch (ExecutionException ex) { handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments()); } catch (Throwable ex) { handleError(ex, userDeclaredMethod, invocation.getArguments()); } return null ; }; return doSubmit(task, executor, invocation.getMethod().getReturnType()); } }
SimpleAsyncTaskExecutor:异步执行用户任务的SimpleAsyncTaskExecutor。每次执行客户提交给它的任务时,它会启动新的线程,并允许开发者控制并发线程的上限(concurrencyLimit),从而起到一定的资源节流作用。默认时,concurrencyLimit取值为-1,即不启用 资源节流 所以它不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程(因此建议我们在使用@Aysnc的时候,自己配置一个线程池,节约资源)
AnnotationAsyncExecutionInterceptor很显然,他是在AsyncExecutionInterceptor的基础上,提供了对@Async注解的支持。所以它是继承它的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor { ... @Override @Nullable protected String getExecutorQualifier (Method method) { Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class); if (async == null ) { async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class); } return (async != null ? async.value() : null ); } }
使用推荐配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @EnableAsync @Configuration public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor () { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor (); executor.setCorePoolSize(10 ); executor.setMaxPoolSize(20 ); executor.setQueueCapacity(1000 ); executor.setKeepAliveSeconds(300 ); executor.setThreadNamePrefix("fsx-Executor-" ); 指定用于新创建的线程名称的前缀。 executor.setRejectedExecutionHandler(new ThreadPoolExecutor .CallerRunsPolicy()); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler () { return new SimpleAsyncUncaughtExceptionHandler (); } }