手写Spring框架-前奏-反射获取Annotation

news2024/11/25 4:50:56

目录

所谓反射

反射机制的作用

反射依赖reflect和Class

反射依赖的Class

Class类的特点

获取Class对象的三种方式

获取类的构造方法并使用

获取类的成员变量并使用

获取类的成员方法并使用

问题引入

解析类的注解

解析成员变量的注解标签

解析方法上的注解

注解获取属性值的底层实现


  • 所谓反射

  • 允许一个java类获得它所有的成员变量和方法,并且显示出来
  • 允许程序在运行时来进行自我检查并且对内部的成员进行操作
  • 反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义
  • 只要给定java类的package和名字,就可以通过反射获得类的所有信息
  • 反射机制的作用

  • 在运行时判断任意一个对象所属的类
  • 在运行时获取类的对象
  • 在运行时访问java对象的属性, 方法和构造方法等
  • 反射依赖reflect和Class

  • java.lang.reflect类库里面主要的类
    • Field :表示类中的成员变量
    • Method :表示类中的方法
    • Constructor :表示类的构造方法
    • Array :该类提供了动态创建数组和访问数组元素的静态方法
  • 反射依赖的Class

  • 用来表示运行时类型信息的对应类
  • 每个类都有唯一一个与之相对应的Class对象
  • Class类为类类型,而Class对象为类类型对象
  • Class类的特点

  • Class类也是类的一种, class则是关键字
  • Class类只有一个私有的构造函数(无法通过new来获取实例),只有JVM能够创建Class类的实例
  • JVM中只有唯一一个和类相对应的Class对象来描述其类型信息
  • 获取Class对象的三种方式

  • Object 一> getClass()
  • 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
  • 通过Class类的静态方法 : forName(String className)(常用)
  • 在运行期间,一个类,只有一个与之相对应的Class对象产生

  • 通过反射读取配置文件,可以得到该类的相关一切信息
  • Class对象就像一面镜子,透过这面镜子可以看到类的结构
  • 获取类的构造方法并使用

  • 带有Declared都是无视修饰符的
  • 通过Class对象可以获取某个类中的:构造方法
  • 获取构造方法:
  • (1)-批量的方法:
    • public Constructor[] getConstructors():所有"公有的"构造方法
    • public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
  • (2)-获取单个的方法
    • public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法
    • public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有
  • (3)-调用构造方法
    • Constructor.newInstance(Object... initargs)
  • 可以通过反射访问私有的构造方法,不过要设置权限setAccessible(true)
  • 案例-构造方法

  • 案例-调用构造方法

  • 案例-结果

  • 获取类的成员变量并使用

  • 需要注意的是:
  • 不带Declared修饰的可以获取父类的字段,带它修饰的不能获取到
  • (1)-批量的:
    • public Field[] getFields():获取所有的"公有字段"
    • public Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有
  • (2)-获取单个的
    • public Field getField(String fieldName):获取某个"公有的"字段
    • public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
  • (3)-设置字段的值
    • Field.set(Object obj,Object value)
    • public void set(Object obj,Object value)
    • 参数说明:
      • 1.obj:要设置的字段所在的对象
      • 2.value:要为字段设置的值
  • 案例-实体类

  • 案例-获得实体类属性并设置属性值

  • 案例-结果

  • 获取类的成员方法并使用

  • (1)-批量的:
  • public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
  • public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
  • (2)-获取单个的:
    • public Method getMethod(String name,Class<?>... parameterTypes)
    • 参数说明:
      • name : 方法名
      • Class ... : 形参的Class类型对象
    • public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
  • (3)-调用方法:
    • Method.invoke(Object obj,Object... args)
    • public Object invoke(Object obj,Object... args):
    • 参数说明:
      • obj : 要调用方法的对象
      • args:调用方式时所传递的实参
  • 方法和成员变量一样都有继承父类之说,两者都一样
  • 带有Declared修饰的都是不能包含父类的
  • 同时指定使用某个成员变量或者方法时要将变量名称和方法名称传入
  • 同时需要先实例化对象再使用
  • 案例-定义方法

  • 案例-调用方法

  • 案例-结果

  • 问题引入

  • 定义注解PersonInfoAnnotation

  • 定义注解CourseInfoAnnotation

  • 使用注解

  • 怎么操作ICPC里面的注解?
  • 解析注解,通过反射获得AnnotatedElement
  • 解析类的注解

  • 运行结果:

  • 解析成员变量的注解标签

  • 1、先获得类对象
  • 2、在获得该类上得所有成员变量
  • 3、遍历成员变量数组
  • 4、判定成员变量上有没有指定得注解
  • 5、有的话就获取注解标签实例,并打印出来

  • 运行结果:

  • 解析方法上的注解

  • 运行结果:

  • CLASS:注解出现在编译好的class文件里,但是注解的相关信息不能出现在运行时
  • 一旦修改注解的生命周期不为RUNTIME,那我们就无法通过反射来获取注解信息
  • 注解获取属性值的底层实现

  • JVM会为注解生成代理对象,注解其实也是一个接口,jvm会生成中间代理对象(在程序运行时生成称为动态代理对象)
  • 通过键值对的形式为注解属性赋值
  • 编译器检查注解的使用范围,将注解信息写入元素属性表
  • 运行时JVM将RUNTIME的所有注解属性取出并最终存入map里
  • 创建AnnotationInvocationHandler实例并传入前面的map
  • JVM使用JDK动态代理为注解生成代理类,并初始化处理器
  • 调用invoke方法,通过传入方法名返回注解对应的属性值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java类加载

类加载的时机 一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期将会经历加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中验证、准备、解析三个阶段统称为连接。 图中加载、验证、准备、初始化和卸载这五个阶段的顺序是…

CDGP数据治理专家认证含金量如何?值得考一个吗?

CDGP&#xff08;Certified Data Governance Professional&#xff09;数据治理专家认证的含金量非常高。该认证证明了持有人拥有数据治理方面的专业知识和技能&#xff0c;能够有效地管理和保护组织的数据资产。 CDGP认证考试内容涵盖数据治理的各个方面&#xff0c;包括数据…

看这家在线教育企业如何通过DHTMLX Scheduler,实现培训管理系统优化

“我们公司目前有一套培训管理系统&#xff0c;用于管理培训学员。目前学员越来越多&#xff0c;老旧的系统已经没法满足需求&#xff0c;导致我们经常需要手动记录学员出勤培训情况&#xff0c;除此之外&#xff0c;系统课程安排只展示时间&#xff0c;没法展示诸如主题&#…

macOS Big Sur 11.7.6 (20G1231) 正式版 ISO、PKG、DMG、IPSW 下载

本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Linux 中创建可引导介质。 2023 年 4 月 10 日&#xff08;北京…

【Vue全家桶】Pinia状态管理

【Vue全家桶】Pinia状态管理 文章目录【Vue全家桶】Pinia状态管理写在前面一、认识Pinia1.1 认识Pinia1.2 为什么使用Pinia&#xff1f;二、 Store2.1 定义Store2.2 Option对象2.3 setup函数2.4 使用定义的Store三、Pinia核心概念State3.1 定义State3.2 操作State3.3 使用选项式…

基于小生境粒子群优化算法的考虑光伏波动性的主动配电网有功无功协调优化(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

C语言基础——指针

文章目录一、指针1.指针的意义2.指针类型表示3.一些操作3.1打印1个变量地址3.2通过地址查看改地址的内容以及修改改地址的内容3.3操作某个空间 -- 4个字节,给他赋值为100&#xff0c;只知道该空间的地址0x8000 00004.指针变量的定义5.指针类型的大小6.指针变量的使用6.1 指针变…

python数据分析-matplotlib折线图知识总结01

python绘图库matplotlib的知识总结一.matplotlib是什么二.matplotlib的安装与导入三.matplotlib的常用函数四.matplotlib绘制折线图的使用方法1.设置图形大小2. 利用数据绘图3.调整x,y轴的刻度,旋转角度,显示描述信息,绘制网格,添加图例4.图形的样式5.绘制多条折线6.显示绘制的…

python知识记录:灵活使用numpy提高python数据分析效率!

NumPy是Python语言的一个第三方库&#xff0c;其支持大量高维度数组与矩阵运算。 作为python科学计算领域的三剑客之一&#xff0c;numpy在数据分析处理方面有着独特的魅力&#xff01; numpy模块的出现更多的是在数组处理的操作上面&#xff0c;并且支持和python常用的数据结…

Transformer在时序预测的应⽤第一弹——Autoformer

Transformer在时序预测的应⽤第一弹——Autoformer 原文地址&#xff1a;Autoformer: Decomposition Transformers with Auto-Correlation for Long-Term Series Forecasting&#xff08;NIPS 2021&#xff09; 做长时间序列的预测 Decomposition把时间序列做拆分&#xff0c…

目标检测——YOLOv7(十三)

简介&#xff1a; 继美团发布YOLOV6之后&#xff0c;YOLO系列原作者也发布了YOLOV7。主要从两点进行模型的优化&#xff1a;模型结构重参化和动态标签分配。 YOLOv7的特点是快&#xff01;相同体量下比YOLOv5精度更高&#xff0c;速度快120%&#xff0c;比YOLOX快180%。 Github…

RabbitMQ消息丢失的情况,以及如何通过代码解决

目录 RabbitMQ消息丢失问题&#xff1a; 代码部分&#xff1a; 完整代码&#xff1a; RabitMQConfig&#xff1a; CourseMQListener: 生产者跟交换机通信的消息丢失解决 &#xff1a; 交换机跟消息队列的消息丢失&#xff1a; 消息队列跟消费者的消息丢失&#xff1a; …

自动处理【支付宝交易支付投诉管理系统】配置指南

大家好&#xff0c;我是小悟 已经有小伙伴开始使用自动处理【支付宝交易支付投诉管理系统】&#xff0c;所以详细介绍一下如何配置。 阅读这篇文章之前&#xff0c;结合这篇【连夜干出来一个自动处理【支付宝交易支付投诉管理系统】&#xff0c;支持多商户】干货食用更佳。 连…

Filter 过滤器 Listener 监听器

Filter web中的过滤器当用户访问服务器资源时&#xff0c;过滤器将请求拦截下来&#xff0c;完成一些通用的操作应用场景如&#xff1a;登录验证、统一编码处理、敏感字符过滤 编写filter对目标资源servlet进行拦截 1. 编写java类&#xff0c;实现filter接口 public class Qu…

智慧医院人员定位系统解决方案,助力医院安全管理智能化

随着经济的发展与生活质量的提升&#xff0c;人们对医疗健康的重视度越来越高&#xff0c;医疗行业也因此蓬勃发展起来。然而&#xff0c;不断扩大的经营规模也给医院安全管理带来挑战和难题。 医院安全管理痛点 1、医疗事件信息获取不及时甚至存在瞒报现象&#xff0c;管理者…

yc博客项目创建-白手起家

初始化项目 1、码云创建代码库 2、下载码云项目到本地 3、IDEA直接生成springboot项目 接入mysql 1、配置文件 2、代码配置 启动项目 访问项目 访问连接&#xff1a; http://localhost:8089/yc-blog/index/listlistContent 注意点&#xff1a;server.servlet.context-path…

Redis用于全局ID生成器、分布式锁的解决方案

全局ID生成器 每个店铺都可以发布优惠卷 当用户抢购时&#xff0c;就会生成订单并保存到tb_voucher_order这张表中&#xff0c;而订单表如果使用数据库自增id就存在一些问题&#xff1a; 1.id的规律性太明显 2.受单表数据量的限制 全局ID生成器&#xff0c;是一种在分布式系…

极光笔记 | 如何在Shopify中使用EngageLab (下)

Sendgird发布的《2022 Global Messaging Engagement Report》中揭示了世界各地的用户更喜欢用哪种方式与品牌互动&#xff0c;结论是&#xff1a;“电子邮件仍然是第一名&#xff08;短信紧随其后&#xff09;”。4800多名受访者中&#xff0c;有18%的人将电子邮件列为他们最常…

普通人是否能从ChatGPT中分一杯羹?

ChatGPT3.0刚刚推出&#xff0c;最开始的时候&#xff0c;人们只是将ChatGPT看作一个很会聊天的机器人&#xff0c;无论问题多么天马行空&#xff0c;它的答案看上去都有理有据。后来&#xff0c;像打开潘多拉魔盒一样&#xff0c;很多人开始拿它编大纲、撰写文案、编代码、创作…

Docker本地推送到hub,以及上传时遇到的问题解决

1.在本地创建一个 Dockerfile FROM ubuntu:latest RUN apt-get update && apt-get install -y curl CMD ["curl", "https://www.baidu.com"]2.在本地构建 Docker 镜像 在创建本地docker镜像的时候[TAG] .和[TAG] /PATH/TO 需要注意dockerfile文件…