Java反射————Method根据方法名称字符串调用方法

引言

之前浏览廖雪峰老师的个人博客网站,无意间发现了关于在Java8中获取参数的方法,随手一转《Java 8中获取参数名称》,没想到今天遇到一个功能,非常符合这种反射调用的使用场景。回看了这篇之前转载的文章,然后根据自己的理解完成了这个功能。

场景描述

功能其实并不复杂。一个设备表中有两个字段,A和B,希望既可以通过A来查找相应记录,又能够通过B来查找相应记录,但问题就在于A和B的样子非常相似,不仅类型相同,就连名字也几乎完全一样(lntDeviceType和ytDeviceType)。

我在Repository中定义了两个方法,分别区分开不同设备类型的查询:

public DeviceType findByYtDeviceType(String ytDeviceType);
public DeviceType findByLntDeviceType(String lntDeviceType);

可是如何在Service中区分应该调用哪个方法呢?第一个能想到的方法就是写死,通过一个值来区分是根据A字段来查询还是B字段来查询,像如下这种形式:

public DeviceType findDeviceType(String column, String deviceTypeStr) {if(column.equals("yt")) {return findByYtDeviceType(deviceTypeStr);} else if (column.equals("lnt")) {return findByLntDeviceType(deviceTypeStr);} else {return null;}
}

上述代码,通过一个colum字符串来得知究竟是通过ytDeviceType字段来查询,还是通过lntDeviceType来查询。问题可以得到解决,但是如果增加了一个C字段怎么办?又增加了一个D字段呢?难道每加一个字段都要加一个else if 写死一个分支?

解决办法——反射调用

思考过后,我想到了通过反射的方式来实现这个功能:

public DeviceType findByDeviceType(String deviceTypeTitle, String deviceType) {// 校验deviceTypeTitle是否正确try {Set<String> deviceTypeColumSet = mapper.convertValue(new DeviceType(), Map.class).keySet();if (!deviceTypeColumSet.contains(deviceTypeTitle))return null;String findBy = "findBy";// 根据deviceTypeTitle查找对应方法名并调用方法Method findByXxDeviceType = dtRepo.getClass().getMethod(findBy + StringUtils.capitalize(deviceTypeTitle),String.class);DeviceType deviceTypeBean = (DeviceType) findByXxDeviceType.invoke(dtRepo, deviceType);logger.info("按类型查找设备类型deviceTypeTitle = " + deviceTypeTitle + "; deviceType = " + deviceType);return deviceTypeBean;} catch (Exception e) {e.printStackTrace();}return null;
}

说明:try块的前三行代码主要是验证deviceTypeTitle是否在DeviceType类型的属性之列,比如DeviceType有A、B两个属性,那么如果deviceTypeTitle是A或者B就符合要求,如果是C就不可以了。StringUtils.capitalize方法主要是将deviceTypeTitle的首字母变为大写,然后加上前缀 “findBy” 从而得到Repository中的方法名

因为不论是用哪个字段来查询,其方法名始终都是  “findByXxxx” ,那何不通过映射自动匹配到对应的方法然后调用呢?这个时候我突然回想起了之前转载的廖雪峰老师的博客《Java 8中获取参数名称》,简单回看之后果然可以解决我的问题,再进一步搜索相关资料之后完成了上述代码。

可以看到我通过拼接一个“findBy”前缀,然后将传入的 deviceTypeTitle 首字母大写与前缀拼接后即可得到Repository中对应的方法名,然后我通过方法名即可进行调用,完全不需要担心未来扩展的问题。即便未来扩展新的设备类型字段,而只需要在Repository中按照 “findByXxxx” 命名规则新加一个查询即可,service中的分发请求完全不需要改动,岂不美哉?!

综上,就是关于通过方法名称字符串映射调用方法的例子,希望能够对大家有所帮助,欢迎文末留言。

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

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

相关文章

一篇文章看懂@Scheduled定时器/@Async/CompletableFuture

一篇文章看懂Scheduled定时器/Async/CompletableFuture Scheduled注解解析&#xff1a; 1.cron&#xff1a;最重要的一个参数 cron表达式[秒] [分] [小时] [日] [月] [周] [年]&#xff08;[年]可省略&#xff09; 简单了解一下&#xff0c;网上有现成的工具 示例&#xff…

一篇搞懂HTTP协议

本文转自 &#xff1a;flyhero 码上实战《一个HTTP打趴80%面试者》 HTTP协议简介 HTTP&#xff08;超文本传输协议&#xff09;是应用层上的一种客户端/服务端模型的通信协议,它由请求和响应构成&#xff0c;且是无状态的。&#xff08;暂不介绍HTTP2&#xff09; 协议&…

注册gmail邮件,遇到“此电话号码无法用于进行验证”该怎么办

注册gmail邮件&#xff0c;遇到“此电话号码无法用于进行验证”该怎么办&#xff1f; 跟浏览器语言的设置有关&#xff0c;将语言改为英文即可&#xff0c;亲测有效&#xff01;

Jackson高级操作————节点树

引言 继《Jackson快速入门》基础篇之后的树模型相关操作。 节点树模型 ObjectMapper构建JsonNode节点树&#xff0c;类似于DOM解析器的XML。 Testpublic void testJsonTree() throws JsonProcessingException, IOException {String jsonString "{\"name\":\…

spring源码分析第一天------源码分析知识储备

spring源码分析第一天------源码分析知识储备 Spring源码分析怎么学? 1、环境准备&#xff1b; 2、思路 看&#xff1a;是什么&#xff1f; 能干啥 想&#xff1a;为什么&#xff1f; 实践&#xff1a;怎么做&#xff1f; 调试的时候&#xff0c;完全可以在…

Jackson高级操作————流式API与JsonGenerator、JsonParser

引言 继《Jackson快速入门》之后的高级相关操作。 Jackson提供了一种对于性能要求应用程序操作json更加高效的方式——流式API&#xff0c;这种方式开销小&#xff0c;性能高&#xff0c;因此&#xff0c;如果应用程序或者程序逻辑对于性能有一定要求&#xff0c;可以使用这种…

Mysql高级教程思维导图

Mysql高级教程思维导图 1、思维导图总览&#xff1a; 2、MySQL架构介绍&#xff1a; 2.1、MySQL简介 2.2、MySQL Linux版安装 2.3、MySQL配置文件 2.4、MySQL逻辑架构介绍 2.5、MySQL存储引擎 2.6、MySQL的用户和权限管理 2.7、MySQL一些杂项配置 ’ 3、索引优化分析 3.1、性…

Eclipse(STS 4)闪退导致EGit插件异常

引言 到目前为止&#xff0c;STS已经闪退过三次了。 问题很棘手&#xff0c;我需要冷静。 首先出现了一个问题就是&#xff0c;EGit无法commit。 第二个问题是切换分支报错。 闪退重启后EGit无法提交代码 观察闪退出现的时机&#xff0c;一般出现在我 commit 代码的时候&…

spring源码分析第二天------spring系统概述以及IOC实现原理

1、Spring5 概述 Spring 是一个开源的轻量级 Java SE&#xff08;Java 标准版本&#xff09;/Java EE&#xff08;Java 企业版本&#xff09;开发应用框架&#xff0c; 其目的是用于简化企业级应用程序开发。 Spring 框架除了帮我们管理对象及其依赖关系&#xff0c;还提供像通…

Linux进阶之路————Linux概述

引言 Linux是一个开源、免费的操作系统。学习Linux知识分为以下几个阶段&#xff1a; 第一阶段&#xff1a;Linux环境下的基本操作命令&#xff0c;包括文件操作命令&#xff08;rm、mkdir、chmod、chown&#xff09;编辑工具使用&#xff08;vi、vim&#xff09;Linux用户管…

spring源码分析第三天------spring核心IOC容器和依赖注入原理

基于XML的依赖注入 1、依赖注入发生的时间 当 Spring IOC 容器完成了 Bean 定义资源的定位、载入和解析注册以后&#xff0c;IOC 容器中已经管理类 Bean 定义的相关数据&#xff0c;但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入&#xff0c;依赖注入在以下两种情况 …

Linux进阶之路————远程登录与vim编辑器

远程登录 远程的Linux系统中&#xff0c;如果希望通过ssh协议登录&#xff0c;那么在Linux需要有一个sshd服务监听22端口&#xff0c;也就是说要想通过ssh登录远程linux&#xff0c;那么linux必须安装sshd服务&#xff0c;并开启。这是一个远程登录成功的前提。 vi、vim编辑器…

JavaWeb中监听器Listener+过滤器filter+拦截器interceptor区别

JavaWeb中监听器Listener过滤器filter拦截器interceptor区别 如果从整个项目中看&#xff0c;一个servlet请求的执行过程就变成了这样context-param–>listener–>filter–>servlet–>interceptor(指的是拦截器) 1.概念 context-param&#xff1a;就是一些需要初…

Linux进阶之路————开机、重启和用户登录注销

关机、重启命令 shutdown 命令&#xff1a; 1&#xff09;shutdown -h now 立即关机 2&#xff09;shutdown -h 1 1分钟之后关机 3&#xff09;shutdown -r now 立即重启 reboot 命令&#xff0c;直接使用&#xff0c;表示立即重启 halt 命令&am…

spring源码分析第四天------springmvc核心原理及源码分析

spring源码分析第四天------springmvc核心原理及源码分析 1、基础知识普及 2、 SpringMVC请求流程 3、SpringMVC代码流程 4、springMVC源码分析 4.1 4.2 4.3 5、Spring MVC 的优化 补充&#xff1a; SpringMVC经典设计是handlerMapping&#xff0c;大家可以看一…

Linux进阶之路————用户管理

引言 前面几篇关于Linux的已经大概领略了Linux的风采&#xff0c;本篇用户管理&#xff0c;将着重总结日常工作中&#xff0c;非常重要的用户管理功能。 主要包括&#xff1a;新增用户、删除用户、查询用户信息、指定/修改密码、切换用户、用户组&#xff0c;以及与用户管理相…

spring源码分析第五天------springAOP核心原理及源码分析

spring源码分析第五天------springAOP核心原理及源码分析 1、 面向切面编程。可以通过预 编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术 切面&#xff08;Aspect&#xff09; 连接点&#xff08;Joinpoint&#xff09; 通知&#x…

Linux进阶之路————Linux运行级别(重置密码)

引言 前面的《Linux进阶之路————开机、重启和用户登录注销》已经简单介绍过Linux系统运行级别的概念&#xff0c;今天来详细介绍和总结一下Linux的运行级别。 inittab配置文件 在配置文件目录下有一个inittab文件/etc/inittab&#xff0c;用于专门存储系统的运行级别&am…

Linux问题处理————命令提示符显示 bash-4.1# 解决方案

引言 本文系Linux学习过程中的一个小插曲。 在使用root用户创建了一个普通的tom 用户之后&#xff0c;系统莫名其妙卡死&#xff0c;重启后&#xff0c;发现命令提示符不再是 “用户名 目录”这种组合&#xff0c;而变成了 bash-4.1# 开头&#xff1a; 解决办法 将/etc/ske…

spring源码分析第六天------spring经典面试问题

spring源码分析第六天------spring经典面试问题 1、Spring5 新特性及应用举例 2、Spring 经典的面试问题 a、什么是 Spring 框架&#xff1f;Spring 框架有哪些主要模块&#xff1f; Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。Spr…