结论先行
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
注解,在子类方法维度的字节码层面,没有继承父类这个注解。
Spring框架是如何查找方法上的注解
事务注解
@Transactional
等注解,查找原理都是一样的。
注解异步执行拦截者AnnotationAsyncExecutionInterceptor获取执行器bean组件
org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor#getExecutorQualifier
调用 AnnotatedElementUtils.findMergedAnnotation(method, Async.class),返回了@Async
注解实例。
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
注解实例。
@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_HIERARCHY
,Perform a full search of the entire type hierarchy, including superclasses and implemented interfaces.
在方法层面,Spring框架已经找到子类的@Async注解,原因是查找注解会搜索整棵类型继承树,包括超类和实现的接口。
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命令