概述
ReflectASM是一個很小的java類庫,它僅僅有5個類,但是卻提供了非常高性能的屬性操作、方法調(diào)用、構(gòu)造方法調(diào)用,它在底層使用了asm(https://www.ibm.com/developerworks/cn/java/j-lo-asm30/index.html)動態(tài)構(gòu)建出字節(jié)碼,這相比于反射,直接方法的調(diào)用性能高出很多。
可以看下官方給出的性能對比:

image.png
原理分析
以MethodAccess為例,使用方式很簡單
MethodAccess access = MethodAccess.get(SomeClass.class);
access.invoke(someObject, "setName", "abc");
通過get方法得到某個類的加強類,直接調(diào)用類上的setName完成方法的調(diào)用,主要的過程便是在get方法中,它通過asm生成SomeClass的代理類,實現(xiàn)了MethodAccess的invoke方法,方法的內(nèi)容是生成SomeClass的所有方法的調(diào)用index,這樣可以通過指定方法名稱的方式調(diào)用類上的方法。直接調(diào)用類上方法的速度肯定要快于反射調(diào)用了
復制類
應用中用到從一個類到另外一個類的copy使用ReflectASM性能會好很多,具體的方式如下:
其中對于耗時的get操作增加了緩存,代理類生成一次就夠了
public class ReflectAsmManager {
private static final ConcurrentMap<Class, MethodAccess> localCache = Maps.newConcurrentMap();
public static MethodAccess get(Class clazz) {
if(localCache.containsKey(clazz)) {
return localCache.get(clazz);
}
MethodAccess methodAccess = MethodAccess.get(clazz);
localCache.putIfAbsent(clazz, methodAccess);
return methodAccess;
}
public static <F,T> void copyProperties(F from, T to) {
MethodAccess fromMethodAccess = get(from.getClass());
MethodAccess toMethodAccess = get(to.getClass());
Field[] fromDeclaredFields = from.getClass().getDeclaredFields();
for(Field field : fromDeclaredFields) {
String name = field.getName();
try {
Object value = fromMethodAccess.invoke(from, "get" + StringUtils.capitalize(name), null);
toMethodAccess.invoke(to, "set" + StringUtils.capitalize(name), value);
} catch (Exception e) {
// 設(shè)置異常,可能會沒有對應字段,忽略
}
}
}
}