Java反射系列(3):从spring反射工具ReflectionUtils说起

news2024/11/24 19:09:47

传送门

在比较早的时候,就讨论过java反射的一些用法及概念:

Java反射系列(1):入门基础

以及反射的基石Class对象! 

Java反射系列(2):从Class获取父类方法说起

今天就从工作中实际的例子来看看反射的应用。 

兼容性引发的"血案"

对于Java程序员来说,调用别人写的类库、使用开源的Jar包似乎无可厚非,甚至是"天经地义"!正是开源的这种无私精神带来了这门语言的繁荣,打造了其遍地开花的生态。而github更是诸多极客们一展风采的宝库舞台,但是这也带来了问题:里面的各种库质量良莠不齐,既有spring这种Java体系"基石"类的产品,也有很多"小而美"的工具包,比如hutool包!

但凡事有利就有弊,最近系统就出现了因为升级hutool包导致功能不可用的场景:

系统里面有一个对db数据自动加解密Mybatis插件,存储时将表里面的数据自动加密,读取时自动解密。其实现原理就是通过Mybatis的拦截器,拦截请求之后,得到原始里面数据,加解密之后用反射机制替换原始数据以此实现动态加解密功能。功能并不复杂,抛开效率性能等因素之外,也是一个比较合理的数据"脱敏"实现机制。但是里面的的反射机制用到了hutool的包,升级时版本不兼容导致功能不可能用,最终用sprig包的ReflectionUtils工具进行了紧急替换,评估之后最终移除了该hutool的引用,后续不再使用!

由此可见,一个好的开源产品,除了功能强大易用之外,升级的版本兼容性也是必不可少的条件之一。这里引用一下网上对此的观点:

ReflectionUtils的原理

对于上面提到的加解密插件,后续可以提供一个实现到码云供参考,这里仅仅表明它是反射机制使用的一个具体场景,不是这里的重点,就不做过多讨论。

目的有三

而这里重点目标有三个:

  • 使用开源包时要慎重,尤其是在生产级应用,越是大公司对此要求越严格
  • ReflectionUtils的使用,熟悉一下里面的API
  • 最终了解反射的用途,深入反射机制

ReflectionUtils的API使用

ReflectionUtils是spring的核心包提供工具类,路径为:org.springframework.util.ReflectionUtils。

在Java反射系列(2):从Class获取父类方法说起里面讨论了Class对象,所以这里重点看看另外几个比较重要的对象:Method,Field。

还是以前面例子的一个简单请求类为例,父类BaseAuthReq :

public class BaseAuthReq
{
    
    /** 应用ID */
    private String clientId;
    
    /** 应用身份密钥 */
    private String clientSecret;
    
    public String getClientId()
    {
        return clientId;
    }
    
    public void setClientId(String clientId)
    {
        this.clientId = clientId;
    }
    
    public String getClientSecret()
    {
        return clientSecret;
    }
    
    public void setClientSecret(String clientSecret)
    {
        this.clientSecret = clientSecret;
    }
}

GetTokenReq继承BaseAuthReq:

public class GetTokenReq extends BaseAuthReq
{
    
    /** 授权码类型 */
    private String grantType;
    
    /** 授权码 */
    private String code;
    
    public String getGrantType()
    {
        return grantType;
    }
    
    public void setGrantType(String grantType)
    {
        this.grantType = grantType;
    }
    
    public String getCode()
    {
        return code;
    }
    
    public void setCode(String code)
    {
        this.code = code;
    }
}

Method

GetTokenReq类里面有2个属性,grantType、code及对应的get、set方法,那通过ReflectionUtils工具类如何获取这些方法呢?

获取所有声明的方法getAllDeclaredMethods

观察下它的API,里面有一个方法,看起来可以满足需求:

public static Method[] getAllDeclaredMethods(Class<?> leafClass)

现在写一个测试方法来验证一下:

@Test
    public void testMethod() {
        // 获取当前类的Class对象
        Class clazz = GetTokenReq.class;
        System.out.println("clazz:" + clazz.getName());

        Method[] allDeclaredMethods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : allDeclaredMethods) {
            System.out.println(method.getName());
        }
    }

运行一下,输出打印结果:

clazz:com.tw.tsm.auth.dto.request.GetTokenReq
// 以下4个为目标方法
setGrantType
getCode
getGrantType
setCode


getClientId
setClientId
setClientSecret
getClientSecret
finalize
wait
wait
wait
equals
toString
hashCode
getClass
clone
notify
notifyAll
registerNatives

从输出可以看出,GetTokenReq类里面2个属性grantType、code对应的get、set方法都打印出来了,但是除此以外,还多了很多方法,它们又是从哪里来的呢?

把上面的输出打印改一下:

@Test
    public void testMethod()
    {
        // 获取当前类的Class对象
        Class clazz = GetTokenReq.class;
        System.out.println("clazz:" + clazz.getName());
        
        Method[] allDeclaredMethods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : allDeclaredMethods)
        {
            // 输出方法所在类,及方法名称
            System.out.println("class:" + method.getDeclaringClass().getName() + ", method:" + method.getName());
        }
    }

运行一下,输出打印结果:

clazz:com.tw.tsm.auth.dto.request.GetTokenReq
class:com.tw.tsm.auth.dto.request.GetTokenReq, method:getGrantType
class:com.tw.tsm.auth.dto.request.GetTokenReq, method:setCode
class:com.tw.tsm.auth.dto.request.GetTokenReq, method:getCode
class:com.tw.tsm.auth.dto.request.GetTokenReq, method:setGrantType
class:com.tw.tsm.auth.dto.BaseAuthReq, method:setClientId
class:com.tw.tsm.auth.dto.BaseAuthReq, method:setClientSecret
class:com.tw.tsm.auth.dto.BaseAuthReq, method:getClientSecret
class:com.tw.tsm.auth.dto.BaseAuthReq, method:getClientId
class:java.lang.Object, method:finalize
class:java.lang.Object, method:wait
class:java.lang.Object, method:wait
class:java.lang.Object, method:wait
class:java.lang.Object, method:equals
class:java.lang.Object, method:toString
class:java.lang.Object, method:hashCode
class:java.lang.Object, method:getClass
class:java.lang.Object, method:clone
class:java.lang.Object, method:notify
class:java.lang.Object, method:notifyAll
class:java.lang.Object, method:registerNatives

从上面的输出可以清晰的看到,getAllDeclaredMethods可以打印类自身及所有父类的方法:

 

Field

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

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

相关文章

pytest--python的一种测试框架--request请求加入headers

一、request headers中的cookie和session机制的作用与区别 Cookie 和 Session 是两种在客户端和服务器之间保持状态的技术。HTTP 协议本身是无状态的&#xff0c;这意味着服务器无法从上一次的请求中保留任何信息到下一次请求。Cookie 和 Session 机制就是为了解决这个问题。 …

240330-大模型资源-使用教程-部署方式-部分笔记

A. 大模型资源 Models - Hugging FaceHF-Mirror - Huggingface 镜像站模型库首页 魔搭社区 B. 使用教程 HuggingFace HuggingFace 10分钟快速入门&#xff08;一&#xff09;&#xff0c;利用Transformers&#xff0c;Pipeline探索AI。_哔哩哔哩_bilibiliHuggingFace快速入…

遥感数字图像处理的学习笔记

相关链接&#xff1a; 遥感数字图像处理实验教程&#xff08;韦玉春&#xff09;--部分实验问题回答 目录 1.什么是图像&#xff0c;什么是数字图像&#xff1f; 2.什么是遥感数字图像&#xff1f;模拟图像(照片)与遥感数字图像有什么区别&#xff1f; 3.什么是遥感数字图像…

小小狠招:巧妙使用HANA数据库的jdbc driver

SAP旗下的HANA数据库&#xff0c;实际上是分为两个系列进行发布&#xff0c;一种是基于本地部署的称之为HANA Platform。另一种是面向Cloud平台的&#xff0c;称之为HANA Cloud。 在实际使用当用&#xff0c;因为两者基本上共用同一代码库&#xff0c;除个别地方略有差异以外&…

C++要学到什么程度才能找到实习?

在考虑 C 学习到何种程度可以找到实习时&#xff0c;以下是一些具体的方向和建议。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我…

HarmonyOS 应用开发之模型切换

本文介绍如何将一个FA模型开发的声明式范式应用切换到Stage模型&#xff0c;您需要完成如下动作&#xff1a; 工程切换&#xff1a;新建一个Stage模型的应用工程。 配置文件切换&#xff1a;config.json切换为app.json5和module.json5。 组件切换&#xff1a;PageAbility/Serv…

如何计算KST指标,昂首资本一个公式计算

在上一篇文章中&#xff0c;Anzo Capital昂首资本和各位投资者一起了解了KST指标&#xff0c;今天我们继续分享如何计算KST指标。 首先投资者可以在时间范围9、12、18和24分析变化率值。 前三个值(时间帧9、12、18)用EMA 26平滑&#xff0c;最后一个值用EMA 39平滑。 然后&…

AndroidStudio出现类似 Could not create task ‘:app:ToolOperatorDemo.main()‘. 错误

先看我们的报错 翻译过来大概意思是:无法创建任务:app:ToolOperatorDemo.main()。 没有找到名称为“main”的源集。 解决方法&#xff1a; 在.idea文件夹下的gradle.xml文件中 <GradleProjectSettings>标签下添加<option name"delegatedBuild" value"f…

前端小白如何理解mvc mvp mvvm

架构、框架、设计模式是都是啥&#xff1f; 架构&#xff1a;抽象出来不同组织或者对象亦或是简单组件&#xff0c;根据需求和各个单元的功能&#xff0c;进行组合排列。 从而完成系统的运行或者是实现目标。 框架&#xff1a;使用什么样的规则&#xff0c;什么样的开发语言&…

政安晨:【Keras机器学习实践要点】(十)—— 自定义保存和序列化

目录 导言 涵盖的API Setup 状态保存自定义 构建和编译保存自定义 结论 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在…

2024年京东云主机租用价格_京东云服务器优惠价格表

2024年京东云服务器优惠价格表&#xff0c;轻量云主机优惠价格5.8元1个月、轻量云主机2C2G3M价格50元一年、196元三年&#xff0c;2C4G5M轻量云主机165元一年&#xff0c;4核8G5M云主机880元一年&#xff0c;游戏联机服务器4C16G配置26元1个月、4C32G价格65元1个月、8核32G费用…

速腾聚创上市后首份财报:冲击年销百万台,押注人形机器人

作者 |老缅 编辑 |德新 港股「激光雷达第一股」速腾聚创&#xff0c;交出了上市后的首份业绩报告。 3月27日&#xff0c;速腾聚创发布了2023年度财报。 报告期内&#xff0c;公司迎来高速的业务增长——2023年总收入达到人民币11.2亿元&#xff0c;同比增长达到111.2%。这主…

Artplayer视频JSON解析播放器源码|支持弹幕|json数据模式

全开源Artplayer播放器视频解析源码&#xff0c;支持两种返回模式&#xff1a;网页播放模式、json数据模式&#xff0c;json数据模式支持限制ip每分钟访问次数UA限制key密钥&#xff0c;也可理解为防盗链 &#xff0c;本播放器带弹幕库。 运行环境 推荐使用PHP8.0 redis扩展…

书生 浦语大模型全链路开源体系

通用大模型成为发展通用人工智能的重要途径 书生 浦语大模型的开源历程 书生 浦语 2.0体系&#xff0c;面向不同的使用需求&#xff0c;每个规格包含三个模型版本&#xff0c;&#xff08;7B、20B&#xff09;InternLM2-Base、InternLM2、InternLM2-Chat。 大模型是回归语言建…

前缀树/字典树Trie

目录 一、Trie的数据结构 二、代码示例 一、Trie的数据结构 Tire通常包括&#xff1a; 1.root节点(根节点)&#xff1a;插入、查找、删除、遍历等操作从root节点开始. 2.flag&#xff1a;结束标志true/false&#xff0c;用于表示当前节点是否为一个完整的字符串的结尾. 3.ke…

第几个幸运数字(蓝桥杯)

文章目录 第几个幸运数字题目描述答案&#xff1a;1905生成法C代码代码详细注释代码思路解释 第几个幸运数字 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 到x星球旅行的游客都被发给一个整数&#xff0c;作为…

软考高级架构师:信息安全保护等级

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

二十四种设计模式与六大设计原则(三):【装饰模式、迭代器模式、组合模式、观察者模式、责任链模式、访问者模式】的定义、举例说明、核心思想、适用场景和优缺点

接上次博客&#xff1a;二十四种设计模式与六大设计原则&#xff08;二&#xff09;&#xff1a;【门面模式、适配器模式、模板方法模式、建造者模式、桥梁模式、命令模式】的定义、举例说明、核心思想、适用场景和优缺点-CSDN博客 目录 装饰模式【Decorator Pattern】 定义…

Android MediaPlayer

MediaPlayer 类是媒体框架最重要的组成部分之一。此类的对象能够获取、解码以及播放音频和视频&#xff0c;而且只需极少量设置。它支持多种不同的媒体源&#xff0c;例如&#xff1a; • 本地资源 • 内部 URI&#xff0c;例如您可能从内容解析器那获取的 URI • 外部网址…

idea从零开发Android 安卓 (超详细)

首先把所有的要准备的说明一下 idea 2023.1 什么版本也都可以操作都是差不多的 gradle 8.7 什么版本也都可以操作都是差不多的 Android SDK 34KPI 下载地址&#xff1a; AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 …