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

 更新时间:2022年10月07日 09:09:13   作者:JAVA旭阳  
这篇文章主要为大家介绍了Hutool开发利器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类的资料请关注脚本之家其它相关文章!

相关文章

  • Java基础之反射原理与用法详解

    Java基础之反射原理与用法详解

    这篇文章主要介绍了Java基础之反射原理与用法,结合实例形式详细分析了java反射的相关概念、原理、使用方法与操作注意事项,需要的朋友可以参考下
    2020-02-02
  • SpringBoot结合dev-tool实现IDEA项目热部署的流程步骤

    SpringBoot结合dev-tool实现IDEA项目热部署的流程步骤

    这篇文章主要给大家介绍了SpringBoot结合dev-tool实现IDEA项目热部署的流程步骤,文章通过图文介绍的非常详细,对大家的学习有一定的帮助,需要的朋友可以参考下
    2023-10-10
  • Java如何在命令行中获取指定数据

    Java如何在命令行中获取指定数据

    这篇文章主要介绍了Java如何在命令行中获取指定数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • WebSocket整合SSM(Spring,Struts2,Maven)的实现示例

    WebSocket整合SSM(Spring,Struts2,Maven)的实现示例

    这篇文章主要介绍了WebSocket整合SSM(Spring,Struts2,Maven)的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • springboot项目如何设置时区

    springboot项目如何设置时区

    这篇文章主要介绍了springboot项目如何设置时区问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 深入理解可视化JVM 故障处理工具

    深入理解可视化JVM 故障处理工具

    这篇文章主要介绍了深入理解可视化JVM 故障处理工具,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Java输出链表倒数第k个节点

    Java输出链表倒数第k个节点

    这篇文章主要介绍了Java输出链表倒数第k个节点的相关内容,涉及三种设计思路及代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • SpringBoot发送邮箱验证码功能

    SpringBoot发送邮箱验证码功能

    这篇文章主要介绍了SpringBoot发送邮箱验证码功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • MyBatis中模糊查询使用CONCAT('%',#{str},'%')出错的解决

    MyBatis中模糊查询使用CONCAT('%',#{str},'%')出错的解

    这篇文章主要介绍了MyBatis中模糊查询使用CONCAT('%',#{str},'%')出错的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • SpringBoot2.0集成Swagger2访问404的解决操作

    SpringBoot2.0集成Swagger2访问404的解决操作

    这篇文章主要介绍了SpringBoot2.0集成Swagger2访问404的解决操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09

最新评论