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

《注解的江湖:一场元数据的“宫斗剧”》

一、你真的懂注解吗

你是否使用过@Autowired却不知道是如何生效的?
这几个注解你一定很熟悉:

  • @Override
  • @Deprecated
  • @Transactional
    那么你有进一步思考过怎么生效的吗?注解到底是什么?注解,到底是信息?还是指令?是标签?还是注释?

二、注解是一封写给反射器的“情书”

  • 注解 = 元数据
    举个例子,你在缅甸被嘎腰子了,这时你想了一个办法,偷偷张贴一张小纸条,上面写着“救我”。那么,路过的人看到这个纸条就会想着替你做点什么。

再来讲讲注解的生命周期:

  • source写完就撕掉(例如override)只作用在源码时期。
  • class 打包了但是JVM不看,作用在class期间(小纸条被翻译成class,但是JVM不看)。
  • runtime这个小纸条可以在程序运行时期被读取。

三、实战一:自定义一个注解,实现“自动字段注入”

“太监宣旨”→ 注解写在类上,反射器执行“圣旨”。

  • 创建一个圣旨
import java.lang.annotation.*;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ShannonAnnotation {int age() default 1 ;String name() default "";
}
  • 宣读圣旨(放在类上)
    @ShannonAnnotation(name = "shannon",age = 18)public static class People{int age;String name;public void sayHello(){System.out.println("hello i am shannon");}}
  • 执行圣旨(反射器调用)
    public static void main(String[] args) {Class<People> peopleClass = People.class;Annotation[] annotations = peopleClass.getAnnotations();// 遍历类上所有的注解,找到我们的圣旨!for (Annotation annotation : annotations) {if (annotation instanceof ShannonAnnotation){ShannonAnnotation annotation1 = (ShannonAnnotation) annotation;System.out.println("age:"+annotation1.age());System.out.println("name:"+annotation1.name());}}
//        invoketry {peopleClass.getMethod("sayHello").invoke(new People());} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {throw new RuntimeException(e);}}
  • 结果:
    在这里插入图片描述

四、实战二:解析 Spring 是如何将“尊贵妃”变“宠妃”

  • 搭建Spring Debug环境
    – 搭建方法见编译Spring
  • 创建一个项目如下:
    在这里插入图片描述
@Service
public class HelloService {public void sayHi(){System.out.println("hello world");}
}
@Service
public class MyService {@Autowiredpublic HelloService helloService;
}

由上可知,在MyService中使用@Autowired注解,将HelloService注入。

  1. 进入方法打断点
    这里解释一下方法的作用,scan方法主要是扫描basePackage的所有bean,注册到BeanDefinitions当中,refresh是真正启动整个容器。
    在这里插入图片描述
    在这个方法打断点org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean,这个方法是注入bean属性的方法。
    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a29bf11cde1243c5a7f96b947d12be9c.png

可以看到,上图,有一个AutoWiredAnnontationBeanPostProcessor类,这个就是@AutoWired的处理方法,点进去看看!
在这里插入图片描述
可以看到上图中,metadata中包含一个injectedElements 包含了HelloService。spring 调用metadatainject方法完成属性的注入!

总结

  1. 注解只是一段信息
  2. 注解不是具体的处理逻辑
  3. 处理逻辑由其他代码实现
http://www.xdnf.cn/news/1053613.html

相关文章:

  • 每日算法刷题Day32 6.15:leetcode枚举技巧7道题,用时1h10min
  • 计网复习知识(17)应用层
  • jQuery 3D透明蓄水池状柱状图插件
  • IDA动态调试环境配置全流程
  • 【Markdown】基础用法汇总(标题、列表、链接、图片、加粗斜体、上下角标、引用块、代码块、公式)
  • 学习日记-day30-6.15
  • Linux安装LLaMA Factory
  • Netty 全面深入学习指南
  • 项目实训个人工作梳理
  • 【算法 day03】LeetCode 203.移除链表元素 | 707.设计链表 | 206.反转链表
  • nodejs中Express框架的基本使用
  • ​​信息系统项目管理师-项目范围管理 知识点总结与例题分析​​
  • Claude Code 实用教程——使用方法详解
  • 庙算兵棋推演AI开发初探(8-神经网络模型接智能体进行游戏)
  • 文本预测和分类任务
  • [笔记] 基于esp32s3用GUI-Guider-1.9.1-GA开发LVGL界面
  • 认识电子元器件之磁传感器
  • Spring有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果?
  • 234. 回文链表
  • SQL 增删改查 —— 笔记篇
  • 面向对象设计原则
  • 深度学习——基于卷积神经网络实现食物图像分类【3】(保存最优模型)
  • React19源码系列之Hooks(useState)
  • Linux中的连接符
  • 谐波减速器 MINIF8 和 MINIF11 的区别
  • 事务传播机制分析:用户注册场景分析
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(2):2020年12月2018年7月
  • leetcode148-排序链表
  • 《Java编程思想》读书笔记:第十二章
  • 01 人工智能起源与诞生