新聞中心
這里有您想知道的互聯(lián)網營銷解決方案
開發(fā)利器Hutool之MapProxy的妙用
概述
Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關API的學習成本,提高工作效率,使Java擁有函數式語言般的優(yōu)雅,讓Java語言也可以“甜甜的”。

創(chuàng)新互聯(lián)-專業(yè)網站定制、快速模板網站建設、高性價比定襄網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式定襄網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋定襄地區(qū)。費用合理售后完善,十余年實體公司更值得信賴。
目前公司項目中主要采用Hutool作為項目的工具包,相對于google的guava, hutool的工具類采用中文注釋,更加符合國人使用。所謂知己知彼,我們需要了解Hutool都具有什么樣的功能,才能夠最大化發(fā)揮它的價值。
本文主要就hutool 5.8.8版本中MapProxy的使用。
場景引入
其實Map在get的時候是比較危險的,你可能不知道它是什么類型,需要進行強制,舉個例子如下:
@Test
public void testMapProxy1() {
MapuserMap = MapUtil.newHashMap(16);
userMap.put("username", "alvin");
userMap.put("age", 20);
// 使用map的時候, 需要進行強轉,一旦類型錯誤,會報錯
String age = (String)userMap.get("age");
}
運行結果:
那有什么更好的解決方案嗎?Hutool提供了一種解決方案給我們。
MapProxy使用
依賴引入
cn.hutool
hutool-all
5.8.8
定義一個可訪問接口
interface MapUser {
String getUsername();
Integer getAge();
MapUser setAge(Integer age);
}
通過MapProxy訪問
@Test
public void testMapProxy2() {
MapuserMap = 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方法,并提供默認值支持,它的類結構圖如下:
- 實現(xiàn)了OptNullBasicTypeFromObjectGetter接口, 提供了基本類型的get, 在不提供默認值的情況下, 如果值不存在或獲取錯誤,返回null, 比如:
mapProxy.getInt("age", 18)。 - 實現(xiàn)了InvocationHandler接口,支持jdk的動態(tài)代理,生成代理對象。
publicT toProxyBean(Class 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類的使用,希望對大家有幫助。
網頁標題:開發(fā)利器Hutool之MapProxy的妙用
網址分享:http://www.dlmjj.cn/article/dphshgh.html


咨詢
建站咨詢
