业务背景
我们经常在开发中记录一些Log、比如说更新了一个对象、我们需要记录一下这个对象的哪些值被更新了、以及更新前后值分别是什么。庆幸java为我们提供了反射的机制。我们可以利用反射去实现此功能
方法实现
public static List<Map<String, String>> getChange(Object originObject, Object newObject)
throws IntrospectionException, InvocationTargetException, IllegalAccessException {
// 存在为null比价就没意义了
if (ObjectUtils.anyNull(originObject, newObject)) {
return null;
}
// 不同类型无法比较
if (ObjectUtils.notEqual(originObject.getClass(), newObject.getClass())) {
return null;
}
// 内容都相等所以没必要比较
if (Objects.deepEquals(originObject, newObject)) {
return Lists.newArrayList();
}
Map<String, String> originFieldValueMap = Maps.newHashMap();
Map<String, String> newFieldValueMap = Maps.newHashMap();
Field[] declaredFields = originObject.getClass().getDeclaredFields();
for (Field field : declaredFields) {
// 检查Field是否为合成字段、如果该字段是合成字段则不进行比较
if (field.isSynthetic()) {
continue;
}
// 实现方式1
// field.setAccessible(true);
// Object o = field.get(originObject);
// Object n = field.get(originObject);
// 实现方式2
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), originObject.getClass());
Method readMethod = propertyDescriptor.getReadMethod();
Object originValue = readMethod.invoke(originObject);
Object newValue = readMethod.invoke(newObject);
if (Objects.deepEquals(originValue, newValue)) {
// 值不相等的话记录属性和值
originFieldValueMap.put(field.getName(), Objects.isNull(originValue) ? null : originValue.toString());
newFieldValueMap.put(field.getName(), Objects.isNull(newValue) ? null : newValue.toString());
}
}
List<Map<String, String>> changes = Lists.newArrayList();
changes.add(originFieldValueMap);
changes.add(newFieldValueMap);
return changes;
}