Hutool开发利器MapProxy类使用技巧详解

目录
  • 概述
  • 场景引入
  • MapProxy使用
  • MapProxy源码解析
  • 总结

概述

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

目前公司项目中主要采用Hutool作为项目的工具包,相对于google的guava, hutool的工具类采用中文注释,更加符合国人使用。所谓知己知彼,我们需要了解Hutool都具有什么样的功能,才能够最大化发挥它的价值。

本文主要就hutool 5.8.8版本中MapProxy的使用。

场景引入

其实Map在get的时候是比较危险的,你可能不知道它是什么类型,需要进行强制,举个例子如下:

@Test
public void testMapProxy1() {
    Map<String, Object> userMap = MapUtil.newHashMap(16);
    userMap.put("username", "alvin");
    userMap.put("age", 20);
    // 使用map的时候, 需要进行强转,一旦类型错误,会报错
    String age = (String)userMap.get("age");
}

运行结果:

那有什么更好的解决方案吗?Hutool提供了一种解决方案给我们。

MapProxy使用

依赖引入

<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.8</version>
</dependency>

定义一个可访问接口

interface MapUser {
    String getUsername();
    Integer getAge();
    MapUser setAge(Integer age);
}

通过MapProxy访问

@Test
public void testMapProxy2() {
    Map<String, Object> userMap = MapUtil.newHashMap(16);
    userMap.put("username", "alvin");
    userMap.put("age", 20);
    MapProxy mapProxy = MapProxy.create(userMap);
    Integer age = mapProxy.getInt("age", 18);
    Assert.assertTrue(age == 20);
    // 通过代理的方式
    MapUser mapUser = mapProxy.toProxyBean(MapUser.class);
    // 后续访问会变的更加安全
    Assert.assertTrue(mapUser.getAge() == 20);
    mapUser.setAge(30);
    Assert.assertTrue(mapUser.getAge() == 30);
}

MapProxy源码解析

Map代理,提供各种getXXX方法,并提供默认值支持,它的类结构图如下:

  • 实现了OptNullBasicTypeFromObjectGetter接口, 提供了基本类型的get, 在不提供默认值的情况下, 如果值不存在或获取错误,返回null, 比如:mapProxy.getInt("age", 18)
  • 实现了InvocationHandler接口,支持jdk的动态代理,生成代理对象。
public <T> T toProxyBean(Class<T> interfaceClass) {
    return (T) Proxy.newProxyInstance(ClassLoaderUtil.getClassLoader(), new Class<?>[]{interfaceClass}, this);
}
  • toProxyBean方法就是生成代理对象,最终会调用代理类的invoke方法,这里的代理类就是MapProxy本身。
public Object invoke(Object proxy, Method method, Object[] args) {
    final Class<?>[] parameterTypes = method.getParameterTypes();
    // 如果调用方法参数为空
    if (ArrayUtil.isEmpty(parameterTypes)) {
        final Class<?> returnType = method.getReturnType();
        // 方法返回值不是void
        if (void.class != returnType) {
            // 匹配Getter
            final String methodName = method.getName();
            String fieldName = null;
            if (methodName.startsWith("get")) {
                // 匹配getXXX
                fieldName = StrUtil.removePreAndLowerFirst(methodName, 3);
            } else if (BooleanUtil.isBoolean(returnType) && methodName.startsWith("is")) {
                // 匹配isXXX
                fieldName = StrUtil.removePreAndLowerFirst(methodName, 2);
            }else if ("hashCode".equals(methodName)) {
                return this.hashCode();
            } else if ("toString".equals(methodName)) {
                return this.toString();
            }
            if (StrUtil.isNotBlank(fieldName)) {
                if (false == this.containsKey(fieldName)) {
                    // 驼峰不存在转下划线尝试
                    fieldName = StrUtil.toUnderlineCase(fieldName);
                }
                return Convert.convert(method.getGenericReturnType(), this.get(fieldName));
            }
        }
        // 如果方法参数不为空
    } else if (1 == parameterTypes.length) {
        // 匹配Setter
        final String methodName = method.getName();
        if (methodName.startsWith("set")) {
            final String fieldName = StrUtil.removePreAndLowerFirst(methodName, 3);
            if (StrUtil.isNotBlank(fieldName)) {
                this.put(fieldName, args[0]);
                final Class<?> returnType = method.getReturnType();
                // 判断返回类型是不是代理类的实例
                if(returnType.isInstance(proxy)){
                    return proxy;
                }
            }
        } else if ("equals".equals(methodName)) {
            return this.equals(args[0]);
        }
    }
    throw new UnsupportedOperationException(method.toGenericString());
}

总结

本文主要讲解了Hutool中的MapProxy类的使用,希望对大家有帮助

以上就是Hutool开发利器MapProxy类使用技巧详解的详细内容,更多关于Hutool开发MapProxy类的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringBoot+Hutool+thymeleaf完成导出Excel的实现方法

    目录 1.引入依赖 2.创建实体类 3.创建导出接口 4.创建html 5.测试导出 导出Excel的框架有很多种,POI相对来说比较老了,很多Excel框架底层都是POI.有EasyPoi.EasyExcel.包括Hutool当中封装的也是POI.唯一不同的是Hutool工具包不局限与做Excel.他里面封装了大量的util,一般现在开发都会用到糊涂. 本篇示例当中不仅仅有后端,而且还提供了前端html,html当中利用js将后端 输出流直接下载为文件. 实现的效果如下:一点击导出文件直接下载

  • SpringBoot 项目使用hutool 工具进行 http 接口调用的处理方法

    目录 写作目的 hutool简单介绍 实践 引用依赖 post get 请求 end 写作目的 在实际的开发过程中一个互联网的项目来说 ,有可能会涉及到调用外部接口的实际业务场景,原生的比如使用httpclient 也能够达到自己想要的结果处理 ,但是其实在实际开发的时候如果没有使用过类似的技术处理的话或多祸首可能会遇见问题所以这里我简单记录一下今天使用到的工具类: hutool 进行接口http 请求调用处理. hutool简单介绍 关于hutool工具包其实本人使用的不多哈 ,这里面其实封装

  • springboot vue接口测试HutoolUtil TreeUtil处理树形结构

    目录 基于springboot+vue的测试平台开发 一.引用 HutoolUtil 二.建表 三.后端接口实现 1. Controller 层 2. DAO层 3. Service 层 四.测试一下 1. 测试结构数据 2. 测试新增默认 基于springboot+vue的测试平台开发 继续更新 上次完成了接口定义功能的前端页面,那么后端现在开始逐一实现对应的功能,首先就是提供模块列表接口,这个模块是支持子层级的,所以大概结构是这样: [ { id: 1, label: '默认', child

  • Hutool开发MapUtil工具类使用示例

    目录 概述 行列互转 键值互换 sort排序操作 join连接操作 过滤转换操作 获取get 总结 概述 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”. 目前公司项目中主要采用Hutool作为项目的工具包,相对于google的guava, hutool的工具类采用中文注释,更加符合国人使用.所谓知己知彼,我们需要了解Hutool都具有什么样的功能,才能够最大化发挥它的价值.

  • 全网最详细Hutool工具详解

    很多方法请看官网地址:hutool官网地址 我们下载:https://www.jb51.net/softs/549331.html 简介 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以"甜甜的". Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当: Hutool是项目中&qu

  • springboot layui hutool Excel导入的实现

    目录 一.导入依赖 (一)其他环境准备 (二)hutool和Excel导入 二.核心代码 三.测试 一.导入依赖 (一)其他环境准备 首先前期根据需求需要搭建springboot+前端的框架,这个根据个人项目来,我是用的springboot+layui.这些不是这里讨论的重点. (二)hutool和Excel导入 <!-- 基本依赖包 --> <dependency> <groupId>cn.hutool</groupId> <artifactId&g

  • Hutool开发利器MapProxy类使用技巧详解

    目录 概述 场景引入 MapProxy使用 MapProxy源码解析 总结 概述 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”. 目前公司项目中主要采用Hutool作为项目的工具包,相对于google的guava, hutool的工具类采用中文注释,更加符合国人使用.所谓知己知彼,我们需要了解Hutool都具有什么样的功能,才能够最大化发挥它的价值. 本文主要就hutool

  • 开发中避免延时操作技巧详解

    目录 前言 使用延时的场景 获取view的宽高 定时查询服务器结果 广播顺序 延时初始化 使用延时的场景 小心使用延时 前言 开发中我们或多或少会涉及到一些场景需要使用延时操作,而延时操作其实并不是一个很好的选择,并不是一个很好的方案,因为它不可控,也可能产生时序的逻辑问题.这次就来盘点一些使用延时操作的场景和如何去避免,本次内容比较基础. 使用延时的场景 在刚接触开发的时候,我们无脑解决问题的方案基本只有两种,异常捕获和延时.异常捕获容易理解,当碰到崩溃又分析不出原因时,往往加个try-cat

  • Android 开发与代码无关技巧详解

    目录 1.如何找到代码 (1)无敌搜索大法 (2)log输出大法 (3)profiler查看大法 (4)万能法找到页面 2.如何解决bug (1)先看再想最后动手 (2)改变现状 (3)是技术问题还是业务问题 (4)张张嘴远胜于动动手 (5)bug解决不了,那就解决提出bug的人 (6)解决了bug之后 3.如何实现不会的功能 (1)不要急着拒绝 (2)大事化小小事化了 心态要稳,天塌了有个高的顶着 1.如何找到代码 作为客户端的开发,工作中经常遇到,后端的同事来帮忙找接口详情.产品经理来询问之

  • Android快速开发系列 10个常用工具类实例代码详解

    打开大家手上的项目,基本都会有一大批的辅助类,今天特此整理出10个基本每个项目中都会使用的工具类,用于快速开发~~在此感谢群里给我发项目中工具类的兄弟/姐妹~ 1.日志工具类L.java package com.zhy.utils; import android.util.Log; /** * Log统一管理类 * * * */ public class L { private L() { /* cannot be instantiated */ throw new UnsupportedOpe

  • java开发MyBatis中常用plus实体类注解符详解

    目录 mybatis-plus常用注解符 1. 表名注解(@TableName) 2. 主键注解(@TableId) 3. 属性注解(@TableField) mybatis-plus常用注解符 1. 表名注解(@TableName) 作用:实体类和数据库中表建立对应关系:如 @TableName("thotset") public class HotsetEntity implements Serializable { private static final long serial

  • Kotlin 嵌套函数开发技巧详解

    目录 1.嵌套函数 2.@JvmOverloads快捷实现函数重载 3.延迟初始化lateinit var 4.@JvmField减少属性set和get方法的生成 1.嵌套函数 业务开发中,我们可能会遇到这样一个场景:一个函数只会被某一处多次调用,且不想让这个函数在该类的其他地方调用,这个时候就需要对这个函数的访问性进行进一步限制. private是无法满足的,这个时候我们就可以使用嵌套函数提供更好的封装: fun test1() { //被限制访问行的函数 fun test2(content:

  • kotlin开发cli工具小技巧详解

    目录 脚手架 开搞 开发调试 jcommander Main 函数声明 压缩模板 放飞自我 生成最终产物 结尾 脚手架 脚手架是为了保证各施工过程顺利进行而搭设的工作平台 而在程序开发过程中,每个工程或者说公司也都需要一个脚手架工具.通过脚手架命令行的形式简化开发流程,避免发生一些人为的相对低级的问题,所以这个也就是为什么叫做脚手架的原因吧. 而由于每个公司的代码规范都不同,一般情况下会主动让开发同学进行工程方面的cv操作,就是成本高并且容易出错.这也就是为什么我们打算写一些这样的工具的原因.

  • Android开发使用URLConnection进行网络编程详解

    本文实例讲述了Android开发使用URLConnection进行网络编程.分享给大家供大家参考,具体如下: URL的openConnection()方法将返回一个URLConnection,该对象表示应用程序和URL之间的通信连接,程序可以通过URLConnection实例向该URL发送请求,读取URL引用的资源.通常创建一个和URL的连接,并发送请求,读取此URL引用的资源. 需要如下步骤: a)通过调用URL对象openConnection()方法来创建URLConnection对象 b)

  • Git操作规范之tag的使用技巧详解

    目录 常用分支 master develop release hotfix 使用 注意 tag规范 打tag场景 tag命名规范 版本类型说明 版本号设置规范 场景举例 新需求 修复bug 重大版本更新 特殊情况 常用分支 首先分享一下我们的分支规范,然后再介绍摸索出的打tag的规范. master master : 主分支 , 最终在master分支对外发布, 此分支只能从其他分支合并,不能再这个分支直接修改 另外所有在master分支的推送应该打标签做记录,方便追溯 例如release合并到

  • Java日期时间类及计算详解

    目录 1. Java中与日期相关的类 1.1 java.util包 ① Date类 ② Calendar 日历类 roll 设置Calendar的容错性 set 1.2 java.time包 ① LocalDate 本地日期类 ② LocalTime 本地时间类 ③ LocalDateTime 本地日期时间类 ④ Instant 类 ⑤ Period 类 ⑥ Duration 类 2. 时间间隔计算 2.1 Period与Duration类 2.1.1 Duration 2.1.2 Period

随机推荐