头图

结论先行

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

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

异步任务代码示例

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

@Component
public class AsyncParentService {
    @Async
    public String parentAsync() {
        return "parentAsync";
    }
}
@Component
public class AsyncService extends AsyncParentService {
    @Override
    public 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
    @Nullable
    protected 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()

    @Nullable
    public 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
    }

参考


简放视野
18 声望0 粉丝

Microservices, Cloud Native, Service Mesh. Java, Go.