如何实现一个增强版本的BeanUtil 工具类

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011955252/article/details/82082905

背景:面对B端系统的开发,会涉及到很对后台页面的管理功能,如果一个页面上有很多字段需要落入数据库,那么在写业务逻辑的时候,需要写很多模型转换的代码,因此写一个简单的框架让模型转换自动完成,是架构师需要考虑的一个问题。

解决方案:

(1)约定大于硬编码,可以使用org.springframework.beans.BeanUtils类的copyProperties,将一个对象的属性的值赋值给另外一个对象,这个方法只是一个简单的实现,实现是基于反射实现,很消耗性能。

(2)在方案一的基础上可以使用asm实现在系统第一次启动的时候,动态实现二进制字节码,然后缓存起来,从第二次开始都从缓存读取二进制字节码。如果模型转换字段改变,系统重新启动会重新生成,这样效率会大大的提高。

---如何对一个对象赋值,可以重写其中的copyProperties,不允许NULL字段赋值

在MVC的开发模式中经常需要将model与pojo的数据绑定,apache和spring的工具包中都有BeanUtils,使用其中的copyProperties方法可以非常方便的进行这些工作,但在实际应用中发现,对于null的处理不太符合个人的需要,例如在进行修改操作中只需要对model中某一项进行修改,那么一般我们在页面上只提交model的ID及需要修改项的值,这个时候使用BeanUtils.copyProperties会将其他的null绑定到pojo中去。为解决这个问题我重写了部分spring BeanUtils的代码如下spring: 3.2.12,其他几个copyProperties方法最终都是调用的这个,

spring的比apache的的多一个带ignoreProperties的

Java代码 

private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)  
        throws BeansException {  
  
    Assert.notNull(source, "Source must not be null");  
    Assert.notNull(target, "Target must not be null");  
  
    Class<?> actualEditable = target.getClass();  
    if (editable != null) {  
        if (!editable.isInstance(target)) {  
            throw new IllegalArgumentException("Target class [" + target.getClass().getName() +  
                    "] not assignable to Editable class [" + editable.getName() + "]");  
        }  
        actualEditable = editable;  
    }  
    PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);  
    List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;  
  
    for (PropertyDescriptor targetPd : targetPds) {  
        Method writeMethod = targetPd.getWriteMethod();  
        if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {  
            PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());  
            if (sourcePd != null) {  
                Method readMethod = sourcePd.getReadMethod();  
                if (readMethod != null &&  
                        ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {  
                    try {  
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {  
                            readMethod.setAccessible(true);  
                        }  
                        Object value = readMethod.invoke(source);  
                        if(value != null){  //只拷贝不为null的属性 by zhao  
                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {  
                                writeMethod.setAccessible(true);  
                            }  
                            writeMethod.invoke(target, value);  
                        }  
                    }  
                    catch (Throwable ex) {  
                        throw new FatalBeanException(  
                                "Could not copy property '" + targetPd.getName() + "' from source to target", ex);  
                    }  
                }  
            }  
        }  
    }  
} 

猜你喜欢

转载自blog.csdn.net/u011955252/article/details/82082905