BeanUtils源码详解

Posted yaohuiqin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BeanUtils源码详解相关的知识,希望对你有一定的参考价值。

  1. debug变量相关的方法都被废弃掉了。private static int debug = 0;

    2、public static void copyProperties(Object dest, Object orig)   从一个对象复制属性到另一个对象上,只要属性名相同即可。

public class BeanUtils {
    public static void copyProperties(Object dest, Object orig)  throws IllegalAccessException, InvocationTargetException {
        BeanUtilsBean.getInstance().copyProperties(dest, orig);
    }
}

  

public class BeanUtilsBean {
    private static final ContextClassLoaderLocal<BeanUtilsBean>
            BEANS_BY_CLASSLOADER = new ContextClassLoaderLocal<BeanUtilsBean>() {
        @Override
        protected BeanUtilsBean initialValue() {
            return new BeanUtilsBean();
        }
    };
    public static BeanUtilsBean getInstance() {
        return BEANS_BY_CLASSLOADER.get();
    }
    private final PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
    public void copyProperties(Object dest, Object orig)
            throws IllegalAccessException, InvocationTargetException {
        if (orig instanceof Map) {
            Map<String, Object> propMap = (Map<String, Object>) orig;
            for (Map.Entry<String, Object> entry : propMap.entrySet()) {
                String name = entry.getKey();
                if (getPropertyUtils().isWriteable(dest, name)) {
                    copyProperty(dest, name, entry.getValue());
                }
            }
        } else /* if (orig is a standard JavaBean) */ {
            PropertyDescriptor[] origDescriptors =
                    getPropertyUtils().getPropertyDescriptors(orig);
            for (int i = 0; i < origDescriptors.length; i++) {
                String name = origDescriptors[i].getName();
                if ("class".equals(name)) {
                    continue; // No point in trying to set an object‘s class
                }
                if (getPropertyUtils().isReadable(orig, name) &&
                        getPropertyUtils().isWriteable(dest, name)) {
                    try {
                        Object value =
                                getPropertyUtils().getSimpleProperty(orig, name);
                        copyProperty(dest, name, value);
                    } catch (NoSuchMethodException e) {
                        // Should not happen
                    }
                }
            }
        }

    }
    public PropertyUtilsBean getPropertyUtils() {
        return propertyUtilsBean;
    }
}

  

public class ContextClassLoaderLocal<T> {

    public synchronized T get() {
        valueByClassLoader.isEmpty();
        try {
            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
            if (contextClassLoader != null) {
                T value = valueByClassLoader.get(contextClassLoader);
                if ((value == null)
                        && !valueByClassLoader.containsKey(contextClassLoader)) {
                    value = initialValue();
                    valueByClassLoader.put(contextClassLoader, value);
                }
                return value;
            }
        } catch (SecurityException e) { /* SWALLOW - should we log this? */ }
        if (!globalValueInitialized) {
            globalValue = initialValue();
            globalValueInitialized = true;
        }
        return globalValue;
    }
}

  

public class PropertyUtilsBean {
    public boolean isWriteable(Object bean, String name)  throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Student student = new Student();
        PropertyDescriptor desc =
                getPropertyDescriptor(bean, name);
        if (desc != null) {
            Method writeMethod = getWriteMethod(bean.getClass(), desc);
            if (writeMethod == null) {
                if (desc instanceof IndexedPropertyDescriptor) {
                    writeMethod = ((IndexedPropertyDescriptor) desc).getIndexedWriteMethod();
                } else if (desc instanceof MappedPropertyDescriptor) {
                    writeMethod = ((MappedPropertyDescriptor) desc).getMappedWriteMethod();
                }
                writeMethod = MethodUtils.getAccessibleMethod(bean.getClass(), writeMethod);
            }
            return (writeMethod != null);
        } else {
            return (false);
        }
    }
    public boolean isReadable(Object bean, String name) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Student student = new Student();
        student.setName("yhq");
        student.setAge(24);
        PropertyDescriptor desc = getPropertyDescriptor(student, "integerage");
        if (desc != null) {
            Method readMethod = getReadMethod(student.getClass(), desc);
            if (readMethod == null) {
                if (desc instanceof IndexedPropertyDescriptor) {
                    readMethod = ((IndexedPropertyDescriptor) desc).getIndexedReadMethod();
                } else if (desc instanceof MappedPropertyDescriptor) {
                    readMethod = ((MappedPropertyDescriptor) desc).getMappedReadMethod();
                }
                readMethod = MethodUtils.getAccessibleMethod(student.getClass(), readMethod);
            }
            return (readMethod != null);
        } else {
            return (false);
        }
    }
    public static Method getReadMethod(Class<?> clazz, PropertyDescriptor descriptor) {
        return (MethodUtils.getAccessibleMethod(clazz, descriptor.getReadMethod()));
    }

    public Method getWriteMethod(Class<?> clazz, PropertyDescriptor descriptor) {
        BeanIntrospectionData data = getIntrospectionData(clazz);
        return (MethodUtils.getAccessibleMethod(clazz,
                data.getWriteMethod(clazz, descriptor)));
    }
}

       4、copyProperty(Object bean, String name, Object value),给bean对的的name属性赋value值

public static void copyProperty(Object bean, String name, Object value)
        throws IllegalAccessException, InvocationTargetException {

        BeanUtilsBean.getInstance().copyProperty(bean, name, value);
    }

   5、public static Map<String, String> describe(Object bean)  返回一个map,key是熟悉名,value是值

   6、public static String[] getArrayProperty(Object bean, String name)  返回String数组,name是属性名,将该属性的值赋值给String[0],再返回数组。

   7、public static String getIndexedProperty(Object bean, String name)   返回指定索引属性的值。

        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        student.setList(list);
        String property23 = BeanUtils.getProperty(student, "list[0]");
        String property33 = BeanUtils.getIndexedProperty(student, "list[0]");
        String property34 = BeanUtils.getIndexedProperty(student, "list",0);
        System.out.println(property23);
        System.out.println(property33);
        System.out.println(property34);    

  8、public static String getMappedProperty(Object bean, String name)

        Map<String,String> map = new HashMap<String,String>();
        map.put("111","aaa");
        map.put("222","bbb");
        student.setMap(map);
        String list1 = BeanUtils.getMappedProperty(student, "map(111)");    

 

 

 

 

 





以上是关于BeanUtils源码详解的主要内容,如果未能解决你的问题,请参考以下文章

BeanUtils.getProperty性能分析

BeanUtils.copyProperties()使用详解+在不同包的区别

Spring 之 BeanUtils.copyProperties(...) 源码简读

结合阿里代码规范约定+源码剖析属性拷贝性能安全问题

Spring提供的BeanUtils源码剖析(附手写copyProperties方法)

Spring提供的BeanUtils源码剖析(附手写copyProperties方法)