关于对象属性拷贝,虽说有现成的工具可用,之前都是自己写的反射进行拷贝,效率比较后,发现效率不高。
自从看了spring的源码,决定优化一下自定义的拷贝工具,主要是吸收spring的优秀思想,即使用内存作为缓存,同样的一个class拷贝时不用每次都进行反射,这样大大提升了效率。
话不多说,直接上源码:
class MethodObj{
private String name;
private Method readMethod;
private Method writeMethod;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Method getReadMethod() {
return readMethod;
}
public void setReadMethod(Method readMethod) {
this.readMethod = readMethod;
}
public Method getWriteMethod() {
return writeMethod;
}
public void setWriteMethod(Method writeMethod) {
this.writeMethod = writeMethod;
}
}
class CacheMethod{
Map<String, MethodObj> methodObjMap = new HashMap<>();
static Map<Class, CacheMethod> classMapCacheMethod = new HashMap<>();
Collection<MethodObj> methodObjs;
public static Collection<MethodObj> getMethodObjList(Class clazz){
CacheMethod cm = classMapCacheMethod.get(clazz);
if(null==cm){
cm = build(clazz);
}
return cm.getMethodObjs();
}
public static MethodObj getMethodObj(Class clazz, String propertyName){
CacheMethod cm = classMapCacheMethod.get(clazz);
if(null==cm){
cm = build(clazz);
}
return cm.getMethodObjMap().get(propertyName);
}
private static CacheMethod build(Class clazz){
CacheMethod cm = new CacheMethod();
for(Method m : clazz.getDeclaredMethods()){
String name = m.getName().replaceAll("set","").replaceAll("get","");
MethodObj methodObj = cm.methodObjMap.get(name);
if(null==methodObj){
methodObj = new MethodObj();
methodObj.setName(name);
}
if(m.getName().startsWith("set")){
methodObj.setWriteMethod(m);
}else if(m.getName().startsWith("get")){
methodObj.setReadMethod(m);
}
cm.methodObjMap.put(name, methodObj);
}
cm.methodObjs = cm.methodObjMap.values();
classMapCacheMethod.put(clazz, cm);
return cm;
}
public Collection<MethodObj> getMethodObjs() {
return methodObjs;
}
public void setMethodObjs(Collection<MethodObj> methodObjs) {
this.methodObjs = methodObjs;
}
public Map<String, MethodObj> getMethodObjMap() {
return methodObjMap;
}
public void setMethodObjMap(Map<String, MethodObj> methodObjMap) {
this.methodObjMap = methodObjMap;
}
public static Map<Class, CacheMethod> getClassMapCacheMethod() {
return classMapCacheMethod;
}
public static void setClassMapCacheMethod(Map<Class, CacheMethod> classMapCacheMethod) {
CacheMethod.classMapCacheMethod = classMapCacheMethod;
}
}
public class FastBeanUtils{
public static void copy(Object dest, Object orig) throws InvocationTargetException, IllegalAccessException {
Collection<MethodObj> methodObjList = CacheMethod.getMethodObjList(orig.getClass());
for(MethodObj m: methodObjList){
MethodObj methodObj = CacheMethod.getMethodObj(dest.getClass(), m.getName());
if(null==methodObj){
continue;
}
Object value = m.getReadMethod().invoke(orig);
methodObj.getWriteMethod().invoke(dest, value);
}
}
}
通过循环1亿次对象拷贝,性能是spring的三倍。