当前位置: 首页 > news >正文

springboot~获取原注解的方法findMergedAnnotation使用场景

这是一个很好的问题,涉及到Spring注解的元注解处理和属性别名机制。让我详细解释一下Spring JMS是如何获取到你自定义注解中的destination值的。

核心机制:Spring的注解属性别名(Attribute Aliasing)

当你在自定义注解中使用@AliasFor@JmsListener的destination属性赋值时,Spring通过以下步骤处理:

1. 注解处理流程

// 你的自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@JmsListener
public @interface MyCustomJmsListener {@AliasFor(annotation = JmsListener.class, attribute = "destination")String value() default "";// 其他属性...
}

2. Spring JMS的内部处理机制

JmsListenerAnnotationBeanPostProcessor是处理@JmsListener的核心类:

// 简化的处理逻辑
public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {// 扫描bean的方法,查找JmsListener注解for (Method method : bean.getClass().getMethods()) {// 这里会使用Spring的AnnotationUtils找到注解JmsListener jmsListener = AnnotatedElementUtils.findMergedAnnotation(method, JmsListener.class);if (jmsListener != null) {processJmsListener(jmsListener, method, bean);}}return bean;}private void processJmsListener(JmsListener jmsListener, Method method, Object bean) {// 获取destination值String destination = jmsListener.destination();// 创建监听器容器...}
}

3. 关键方法:AnnotatedElementUtils.findMergedAnnotation()

这是Spring处理注解属性的核心方法:

// Spring内部的处理逻辑
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {// 1. 查找直接或元注解Annotation[] annotations = element.getAnnotations();for (Annotation ann : annotations) {// 2. 如果是目标注解直接返回if (annotationType.isInstance(ann)) {return (A) ann;}// 3. 递归处理元注解Annotation[] metaAnnotations = ann.annotationType().getAnnotations();for (Annotation metaAnn : metaAnnotations) {if (annotationType.isInstance(metaAnn)) {// 4. 处理属性别名映射return synthesizeAnnotation(ann, metaAnn, element);}}}return null;
}

4. 属性别名解析过程

private static <A extends Annotation> A synthesizeAnnotation(Annotation sourceAnnotation, Annotation metaAnnotation, AnnotatedElement element) {Map<String, Object> attributeMap = new HashMap<>();// 获取元注解的属性Method[] metaMethods = metaAnnotation.annotationType().getDeclaredMethods();for (Method metaMethod : metaMethods) {String attributeName = metaMethod.getName();// 检查源注解是否有对应的别名属性Method sourceMethod = findAliasMethod(sourceAnnotation, attributeName);if (sourceMethod != null) {// 使用源注解的值覆盖元注解的值Object value = invokeMethod(sourceMethod, sourceAnnotation);attributeMap.put(attributeName, value);} else {// 使用元注解的默认值Object value = invokeMethod(metaMethod, metaAnnotation);attributeMap.put(attributeName, value);}}// 创建合成注解return AnnotationUtils.synthesizeAnnotation(attributeMap, metaAnnotation.annotationType(), element);
}

5. 实际示例

假设你的使用方式如下:

@Component
public class MyMessageListener {@MyCustomJmsListener("my-queue")public void handleMessage(String message) {// 处理消息}
}

Spring JMS的处理过程:

  1. 发现注解:扫描到@MyCustomJmsListener注解
  2. 识别元注解:发现@MyCustomJmsListener@JmsListener元注解标记
  3. 属性合并:通过@AliasForvalue="my-queue"映射到destination属性
  4. 创建监听器:使用合成后的@JmsListener(destination = "my-queue")创建JMS监听容器

6. 验证方法

你可以通过以下方式验证这个机制:

@SpringBootTest
class JmsListenerTest {@Autowiredprivate JmsListenerEndpointRegistry endpointRegistry;@Testvoid testCustomAnnotation() {// 检查监听器容器是否创建成功Collection<MessageListenerContainer> containers = endpointRegistry.getListenerContainers();for (MessageListenerContainer container : containers) {if (container instanceof JmsListenerEndpointRegistry) {// 验证destination是否正确设置String destination = ((AbstractJmsListenerContainer) container).getDestination();System.out.println("监听的destination: " + destination);}}}
}

总结

Spring通过AnnotatedElementUtils和注解属性别名机制,能够正确识别你自定义注解中通过@AliasFor映射的属性值。这种设计使得注解组合和自定义变得非常灵活,是Spring框架强大的元编程能力的体现。

http://www.zskr.cn/news/10383.html

相关文章:

  • Catalan数(卡特兰数)
  • ubuntu22.04 安装xrdp
  • CSP-J 2025 初赛试题解析(第一部分:阅读程序题(一)(16-21)) - 指南
  • 面试八股文之——JVM与并发编程/多线程 - 教程
  • 52805 JLINK 端口保护机制硬件保护具体流程分析;
  • 构建你的 MCP 能力层:.NET 9 + SK 的系统方案
  • FOC之电机模型
  • paddleOCR 图片识别
  • VS依赖项显示黄色感叹号、红色叉叉,NU1101找不到包异常情况处理方案
  • AT_arc197_e [ARC197E] Four Square Tiles
  • 不限速网盘盘点,五款免费网盘综合对比
  • Linux应用研发(君正T23):三网智能切换及配网功能
  • 学习笔记508— 威联通安装使用Zerotier One
  • Adaptix C2:跨平台渗透测试与对抗仿真框架
  • 完整教程:深度学习-神经网络(上篇)
  • WBS、甘特图、关键路径……项目计划的五大核心概念一文全懂
  • 关于CompatibilityHID例程的使用
  • 实用指南:通过ssh远程linux 盒子
  • Https模式访问wcf方法配置
  • Day05---数据类型的转换
  • 效率党的图片处理新选择:滴答修——在线全能工具箱,免费且强大
  • 923-
  • 绝了!TaskMatrix Pro - 谷歌、火狐浏览器任务管理插件,四象限矩阵让拖延症瞬间消失 - 开源免费
  • perl -MCPAN -e install GD;
  • 对之前部署hbase总结
  • Fluent Bit采集k8s日志
  • Typora+Cnblog实现Markdown图片自动上传
  • 嵌套粒子群优化(Nested PSO)的电力系统经济调度方案
  • Google智能体Jules小试牛刀
  • 搞笑椅子机房语录