例如: BeanUtils.copyProperties(beforeObj, route, new String[] { "id", "createDate", "modifyDate" });java
包名爲:org.springframework.beansspring
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對象 * java.lang.Class類裏邊有不少實用的方法 當你獲得一個對象的Class對象以後就能夠調用這些方法 * 例如: * Method m = gTResultVo.getClass().getDeclaredMethod("set" + classMethod, String.class); * m.invoke(gTResultVo, value); * 經過Class類的getDeclaredMethod獲取gTResultVo類的某個set方法,而後進行賦值 */ 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類表示JavaBean類經過存儲器導出一個屬性。 * 主要方法: * 一、getPropertyType(),得到屬性的Class對象。 * 二、getReadMethod(),得到用於讀取屬性值的方法;getWriteMethod(),得到用於寫入屬性值的方法。 * 三、hashCode(),獲取對象的哈希值。 * 四、setReadMethod(Method readMethod),設置用於讀取屬性值的方法;setWriteMethod(MethodwriteMethod),設置用於寫入屬性值的方法; */ PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable); /** * Arrays.asList(ignoreProperties):把String[]轉換成列表 */ List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); for (PropertyDescriptor targetPd : targetPds) { Method writeMethod = targetPd.getWriteMethod();//得到用於寫入屬性值的方法 /** * 判斷是否有忽略屬性或當前屬性是否在忽略屬性中 * !ignoreList.contains(targetPd.getName()):利用列表的contains直接判斷是否含有該屬性 */ if (writeMethod != null && (ignoreList == 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);//獲取source的該屬性值 if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { writeMethod.setAccessible(true); } writeMethod.invoke(target, value);//利用獲取到的writeMethod給target賦值 } catch (Throwable ex) { throw new FatalBeanException( "Could not copy property '" + targetPd.getName() + "' from source to target", ex); } } } } } }
public static boolean isAssignable(Class<?> lhsType, Class<?> rhsType) { Assert.notNull(lhsType, "Left-hand side type must not be null"); Assert.notNull(rhsType, "Right-hand side type must not be null"); /** * instanceof: * 用法:boolean 對象 instanceof 類型 * 解釋:用於判斷某一個對象是不是該類型的實例 * * Class.isAssignableFrom(Class<?> clazz) * 用法:boolean class.isAssignableFrom(Class<?> clazz) * 解釋:calss是否與參數clazz相同,或class是clazz的父類或接口。 */ if (lhsType.isAssignableFrom(rhsType)) { return true; } /** * isPrimitive:肯定指定的Class對象表示一個基本類型,當且僅當這個類表示一個基本類型此方法返回true。 * primitiveWrapperTypeMap:包裝類做爲key,原始類型做爲value的基本類型集合;例如:primitiveWrapperTypeMap.put(Boolean.class, boolean.class); */ if (lhsType.isPrimitive()) { Class<?> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType); if (lhsType == resolvedPrimitive) { return true; } } /** * primitiveTypeToWrapperMap:原始類型做爲key,包裝類做爲value的基本類型集合; */ else { Class<?> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType); if (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)) { return true; } } return false; }