class BeanUtils {

    public static void copyProperties(Object src, Object dst, String... ignoreFields) {
        Class srcClazz = src.getClass();
        Class distClazz = dst.getClass();
        Method[] methods = distClazz.getMethods();
        List<String> ignoreFiledList = Arrays.asList(ignoreFields);
        for (Method dstMethod : methods) { // 遍历目标对象的方法
            if (Modifier.isStatic(dstMethod.getModifiers())
                || !ReflectUtils.isBeanPropertyReadMethod(dstMethod)) {
                // 不是static方法， 是getter方法
                continue;
            }
            String propertyName = ReflectUtils.getPropertyNameFromBeanReadMethod(dstMethod);
            if (ignoreFiledList.contains(propertyName)) {
                // 忽略字段
                continue;
            }
            Class dstReturnType = dstMethod.getReturnType();
            try { // 同时目标字段还需要有set方法
                Method dstSetterMethod = ReflectUtils.getPropertySetterMethod(distClazz, propertyName, dstReturnType);
                if (dstSetterMethod != null) {
                    // 再检查原始对象方法
                    Method srcGetterMethod = ReflectUtils.getPropertyGetterMethod(srcClazz, propertyName);
                    // 原始字段有getter方法
                    Class srcReturnType = srcGetterMethod.getReturnType();
                    if (srcReturnType.equals(dstReturnType)) { // 原始字段和目标字段返回类型一样
                        Object val = srcGetterMethod.invoke(src); // 从原始对象读取值
                        if (val != null) {
                            dstSetterMethod.invoke(dst, val); // 设置到目标对象
                        }
                    }
                }
            } catch (Exception ignore) {
                // ignore 下一循环
            }
        }
    }

}