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
	}

参考

相关推荐
小蒜学长20 分钟前
springboot餐厅信息管理系统设计(代码+数据库+LW)
java·数据库·spring boot·后端
Jabes.yang1 小时前
Java大厂面试实录:从Spring Boot到微服务的技术探讨
java·spring boot·spring cloud·微服务·技术面试
咖啡Beans2 小时前
SpringBoot集成MongoDB使用
spring boot·mongodb
q_19132846952 小时前
基于RuoYi框架+Mysql的汽车进销存后台管理系统
数据库·vue.js·spring boot·mysql·汽车·个人开发·若依
悟能不能悟3 小时前
springboot在DTO使用service,怎么写
java·数据库·spring boot
__XYZ3 小时前
RedisTemplate 实现分布式锁
java·spring boot·redis·分布式·junit
不能再留遗憾了3 小时前
【SpringCloud】Sentinel
spring·spring cloud·sentinel
Cc00108524 小时前
【AI学习笔记】用AI生成spring boot + redis
spring boot·笔记·学习·ai编程
whltaoin4 小时前
AI 超级智能体全栈项目阶段五:RAG 四大流程详解、最佳实践与调优(基于 Spring AI 实现)
java·人工智能·spring·rag·springai
thginWalker4 小时前
使用Spring Boot构建Web服务层
spring boot