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類的資料請關注腳本之家其它相關文章!
相關文章
SpringMVC使用ResponseEntity實現文件上傳下載
這篇文章主要為大家介紹了SpringMVC使用ResponseEntity實現文件上傳下載,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05Windows下使用Graalvm將Springboot應用編譯成exe大大提高啟動和運行效率(推薦)
這篇文章主要介紹了Windows下使用Graalvm將Springboot應用編譯成exe大大提高啟動和運行效率,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02java HashMap,TreeMap與LinkedHashMap的詳解
這篇文章主要介紹了 java HashMap,TreeMap與LinkedHashMap的詳解的相關資料,這里提供實例代碼,幫助大家學習理解 這部分的內容,需要的朋友可以參考下2016-11-11