大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
@EnableAsync注解
/** * 可自定义扫描的注解 */
Class<? extends Annotation> annotation() default Annotation.class;
/** * 采用代理的方式,如果设置为true,后续会使用CGLIB进行代理 */
boolean proxyTargetClass() default false;
/** * 使用代理的模式 */
AdviceMode mode() default AdviceMode.PROXY;
/** * 注解处理的顺序 */
int order() default Ordered.LOWEST_PRECEDENCE;
ProxyAsyncConfiguration
@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
//创建一个异步注解处理器
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
//将从容器中获取到的 Executor 和 ExceptionHandler设置到对象中
bpp.configure(this.executor, this.exceptionHandler);
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
//设置自定义的 异步注解
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
//设置代理方式
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
//设置加载顺序
bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
return bpp;
}
/** * 获取到注解是否开启异步代理 */
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName()));
if (this.enableAsync == null) {
throw new IllegalArgumentException(
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
}
}
/** * 从容器中找到实现了 AsyncConfigurer 类,然后获取到自定义的 线程执行器和异常处理器;默认为null */
@Autowired
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
//默认会使用第一个配置对象
Supplier<AsyncConfigurer> configurer = SingletonSupplier.of(() -> {
List<AsyncConfigurer> candidates = configurers.stream().collect(Collectors.toList());
if (CollectionUtils.isEmpty(candidates)) {
return null;
}
if (candidates.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
return candidates.get(0);
});
this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
}
//这里会返回一个Supplier对象用于在 AsyncExecutionAspectSupport 当中设置默认的线程池
private <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> provider) {
return () -> {
//如果不配置 AsyncConfigurer 这里就会返回null
AsyncConfigurer configurer = supplier.get();
return (configurer != null ? provider.apply(configurer) : null);
};
}
AsyncAnnotationBeanPostProcessor
1. setBeanFactory()
实现了 BeanFactoryAware 接口,初始化 AsyncAnnotationBeanPostProcessor 时会调用内部的**setBeanFactory() **方法设置切面
2. postProcessAfterInitialization
方法在容器创建好之后执行,给bean对象创建一个代理对象
AsyncAnnotationAdvisor
public AsyncAnnotationAdvisor(
@Nullable Supplier<Executor> executor, @Nullable Supplier<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) {
}
//构建一个通知对象
this.advice = buildAdvice(executor, exceptionHandler);
//根据注解构造一个切点,切点用于对类进行匹配,匹配了之后真正执行的是 Advice 来进行
//返回一个ComposablePointcut支持多个过滤方式进行匹配,就是将多个ClassFilter和MethodMather进行合并
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
AnnotationAsyncExecutionInterceptor
/** * 通过父类的构造器,设置一个默认的线程池的获取方式 */
public AsyncExecutionAspectSupport(@Nullable Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
// defaultExecutor就是在 ProxyAsyncConfiguration 中设置的Supplier对象,如果获取不到就调用
this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
this.exceptionHandler = SingletonSupplier.of(exceptionHandler);
}
1. getExecutorQualifier()
protected String getExecutorQualifier(Method method) {
//获取到方法上面的注解,获取到vlue值,然后通过value值去确定线程池
Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class);
if (async == null) {
async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class);
}
return (async != null ? async.value() : null);
}
2. invoke()
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);
//确定异步使用的线程池 默认使用 SimpleAsyncTaskExecutor
AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod);
if (executor == null) {
throw new IllegalStateException();
}
//包装成 Callable 类的任务
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());
}
3. determineAsyncExecutor()
protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
//初始获取的会是null
AsyncTaskExecutor executor = this.executors.get(method);
if (executor == null) {
Executor targetExecutor;
//调用复写的方法通过注解来获取到对应的value来确定容器中的线程池名称
String qualifier = getExecutorQualifier(method);
if (StringUtils.hasLength(qualifier)) {
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
}
else {
//调用默认的 SingletonSupplier 对象来获取到对应的默认线程池。如果设置的对象都没有获取到,就会调用 getDefaultExecutor() 方法
targetExecutor = this.defaultExecutor.get();
}
if (targetExecutor == null) {
return null;
}
executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
(AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
//缓存上
this.executors.put(method, executor);
}
return executor;
}
4. getDefaultExecutor()
AsyncExecutionInterceptor复写的方法,如果都容器中都没有获取到对应的线程池,那么就返回 SimpleAsyncTaskExecutor
protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
//调用父类方法去获取线程池
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
面试题
spring中Async注解是使用线程池进行异步处理,还是使用单线程?
答:根据spring容器中配置的 ObjectProvider<AsyncConfigurer> configurers 配置对象进行配置线程池还是单线程进行异步处理;如果没有指定配置对象那么默认就会去容器中查找 TaskExecutor 类型如果抛出异常就会去找名称为 taskExecutor 类型为 Executor 的线程池;如果都没有则使用默认 SimpleAsyncTaskExecutor 单线程进行异步处理
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/157804.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...