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

结论先行

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

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

异步任务代码示例

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

java 复制代码
@Component
public class AsyncParentService {
    @Async
    public String parentAsync() {
        return "parentAsync";
    }
}
java 复制代码
@Component
public class AsyncService extends AsyncParentService {
    @Override
    public String parentAsync() {
        return "async";
    }
}

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

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

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

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

org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor#getExecutorQualifier

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

java 复制代码
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注解实例。

java 复制代码
	@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注解,原因是查找注解会搜索整棵类型继承树,包括超类和实现的接口

java 复制代码
	private static MergedAnnotations findAnnotations(AnnotatedElement element) {
		return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none());
	}

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

java 复制代码
	/**
	 * 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
	}

参考

相关推荐
用户908324602738 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
用户8307196840821 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解1 天前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解1 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记1 天前
Spring Boot Web MVC配置详解
spring boot·后端
初次攀爬者2 天前
Kafka 基础介绍
spring boot·kafka·消息队列
用户8307196840822 天前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解2 天前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端