您的位置:首页 > 汽车 > 新车 > Spring框架是如何查找方法上的异步任务注解@Async

Spring框架是如何查找方法上的异步任务注解@Async

2024/7/2 15:47:03 来源:https://blog.csdn.net/shupili141005/article/details/139637959  浏览:    关键词:Spring框架是如何查找方法上的异步任务注解@Async

结论先行

Spring框架层面,查找方法上的注解的原理与机制是一样的。

在方法层面,Spring框架已经找到子类的@Async注解,原因是查找注解会搜索整棵类型继承树,包括超类和实现的接口

异步任务代码示例

`@Async``注解,在父类方法上声明定义。子类覆盖这个方法,但没有声明异步注解。

@Component
public class AsyncParentService {@Asyncpublic String parentAsync() {return "parentAsync";}
}
@Component
public class AsyncService extends AsyncParentService {@Overridepublic String parentAsync() {return "async";}
}

通过Arthas的jad命令反编译指定已加载类的源码。
@Async注解,在子类方法维度的字节码层面,没有继承父类这个注解。
Java字节码

Spring框架是如何查找方法上的注解

事务注解@Transactional等注解,查找原理都是一样的。

注解异步执行拦截者AnnotationAsyncExecutionInterceptor获取执行器bean组件

org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor#getExecutorQualifier

调用 AnnotatedElementUtils.findMergedAnnotation(method, Async.class),返回了@Async注解实例。
AnnotationAsyncExecutionInterceptor.getExecutorQualifier()

public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor {@Override@Nullableprotected String getExecutorQualifier(Method method) {// Maintainer's note: changes made here should also be made in// AnnotationAsyncExecutionAspect#getExecutorQualifier// 这里返回了异步任务注解实例Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class);if (async == null) {async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class);}return (async != null ? async.value() : null);}
}

注解元素工具类AnnotatedElementUtils查找合并的注解

org.springframework.core.annotation.AnnotatedElementUtils#findMergedAnnotation

调用 findAnnotations(element),返回了@Async注解实例。
AnnotatedElementUtils.findMergedAnnotation()

	@Nullablepublic static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {// Shortcut: directly present on the element, with no merging needed?if (AnnotationFilter.PLAIN.matches(annotationType) ||AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {return element.getDeclaredAnnotation(annotationType);}// Exhaustive retrieval of merged annotations...return findAnnotations(element) // 这里返回了注解实例.get(annotationType, null, MergedAnnotationSelectors.firstDirectlyDeclared()).synthesize(MergedAnnotation::isPresent).orElse(null);}

查找特定的注解

org.springframework.core.annotation.AnnotatedElementUtils#findAnnotations

其查找策略使用SearchStrategy.TYPE_HIERARCHYPerform a full search of the entire type hierarchy, including superclasses and implemented interfaces.
在方法层面,Spring框架已经找到子类的@Async注解,原因是查找注解会搜索整棵类型继承树,包括超类和实现的接口
AnnotatedElementUtils.findAnnotations()

	private static MergedAnnotations findAnnotations(AnnotatedElement element) {return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none());}

搜索策略
org.springframework.core.annotation.MergedAnnotations.SearchStrategy#TYPE_HIERARCHY

	/*** Search strategies supported by* {@link MergedAnnotations#from(AnnotatedElement, SearchStrategy)} and* variants of that method.** <p>Each strategy creates a different set of aggregates that will be* combined to create the final {@link MergedAnnotations}.*/enum SearchStrategy {/*** Find only directly declared annotations, without considering* {@link Inherited @Inherited} annotations and without searching* superclasses or implemented interfaces.*/DIRECT,/*** Find all directly declared annotations as well as any* {@link Inherited @Inherited} superclass annotations.*/INHERITED_ANNOTATIONS,/*** Find all directly declared and superclass annotations.*/SUPERCLASS,/*** Perform a full search of the entire type hierarchy, including* superclasses and implemented interfaces.* <p>Superclass annotations do not need to be meta-annotated with* {@link Inherited @Inherited}.*/TYPE_HIERARCHY,/*** Perform a full search of the entire type hierarchy on the source* <em>and</em> any enclosing classes.*/TYPE_HIERARCHY_AND_ENCLOSING_CLASSES}

参考

  • jad - 反编译指定已加载类的源码 – Arthas命令

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com