欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Hutool開發(fā)利器MapProxy類使用技巧詳解

 更新時間:2022年10月07日 09:09:13   作者:JAVA旭陽  
這篇文章主要為大家介紹了Hutool開發(fā)利器MapProxy類使用技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

概述

Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關API的學習成本,提高工作效率,使Java擁有函數式語言般的優(yōu)雅,讓Java語言也可以“甜甜的”。

目前公司項目中主要采用Hutool作為項目的工具包,相對于google的guava, hutool的工具類采用中文注釋,更加符合國人使用。所謂知己知彼,我們需要了解Hutool都具有什么樣的功能,才能夠最大化發(fā)揮它的價值。

本文主要就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);
    // 后續(xù)訪問會變的更加安全
    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的動態(tài)代理,生成代理對象。
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開發(fā)利器MapProxy類使用技巧詳解的詳細內容,更多關于Hutool開發(fā)MapProxy類的資料請關注腳本之家其它相關文章!

相關文章

  • java 三元操作符用法說明

    java 三元操作符用法說明

    這篇文章主要介紹了java 三元操作符用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 使用Idea快速搭建SpringMVC項目的詳細步驟記錄

    使用Idea快速搭建SpringMVC項目的詳細步驟記錄

    這篇文章主要給大家介紹了關于使用Idea快速搭建SpringMVC項目的詳細步驟,Spring?MVC是一種基于MVC模式的框架,它是Spring框架的一部分,它提供了一種更簡單和更有效的方式來構建Web應用程序,需要的朋友可以參考下
    2024-05-05
  • SpringMVC使用ResponseEntity實現文件上傳下載

    SpringMVC使用ResponseEntity實現文件上傳下載

    這篇文章主要為大家介紹了SpringMVC使用ResponseEntity實現文件上傳下載,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Windows下使用Graalvm將Springboot應用編譯成exe大大提高啟動和運行效率(推薦)

    Windows下使用Graalvm將Springboot應用編譯成exe大大提高啟動和運行效率(推薦)

    這篇文章主要介紹了Windows下使用Graalvm將Springboot應用編譯成exe大大提高啟動和運行效率,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • SpringBoot模板引擎之Thymeleaf的使用

    SpringBoot模板引擎之Thymeleaf的使用

    這篇文章主要介紹了SpringBoot模板引擎之Thymeleaf的使用,模板引擎是以業(yè)務邏輯層和表現層分離為目的的,將規(guī)定格式的模板代碼轉換為業(yè)務數據的算法實現,它可以是一個過程代碼、一個類,甚至是一個類庫,需要的朋友可以參考下
    2023-10-10
  • java HashMap,TreeMap與LinkedHashMap的詳解

    java HashMap,TreeMap與LinkedHashMap的詳解

    這篇文章主要介紹了 java HashMap,TreeMap與LinkedHashMap的詳解的相關資料,這里提供實例代碼,幫助大家學習理解 這部分的內容,需要的朋友可以參考下
    2016-11-11
  • java之minio文件服務器的日常操作

    java之minio文件服務器的日常操作

    本文介紹如何在Java項目中配置Minio服務,通過創(chuàng)建minioConfig和minioDto來管理連接信息,并通過minioUtils工具類實現文件的上傳、下載和刪除功能,詳細說明了如何從application.yml文件中讀取配置,并強調了避免static情況下minioDto為null的問題,另外,提到刪除操作是延遲的
    2024-10-10
  • 基于Transactional事務的使用以及注意說明

    基于Transactional事務的使用以及注意說明

    這篇文章主要介紹了Transactional事務的使用以及注意說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring服務注解有哪些

    Spring服務注解有哪些

    這篇文章主要介紹了Spring服務注解,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2016-11-11
  • Spring?Boot日志基礎使用之如何設置日志級別

    Spring?Boot日志基礎使用之如何設置日志級別

    這篇文章主要介紹了Spring?Boot日志基礎使用設置日志級別的方法,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09

最新評論