学习笔记,记录下项目中有趣的地方,从现在开始
场景
采购相关的订单状态记录,订单状态从创建到完成中间的状态很多,为了更好的追溯数据和别的某些领导的需要记录下订单每次状态变更,因为要记录变更前状态和变更后状态,所以放弃了AOP,用自定义注解+反射少些一点侵入代码
思路
因为不同业务的实体里面业务单号和状态字段大部分情况下不会一样,使用自定义注解加到实体的字段上,通过反射获取加过注解的字段,然后通过注解里面的值value来找到自己想要的字段,然后定义一个方法入参是泛型然后开始操作就行了
注解
用来标记某个方法,成员变量,类,枚举等,每个注解都要有他的使用范围@Target和生命周期@Retention
自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldValue {
FieldEnum value();
}
实体
@Data
public class test{
private String businessOrderNum;
}
枚举
public enum FieldEnum {
BUSINESS_NUM("业务单号",0),
OPERATOR("操作人",1),
REMARKS("备注",2),
STATUS("状态",3)
;
/**
* 描述
*/
private String description;
/**
* 下标 看着用着顺眼
*/
private Integer index;
//自行get set 构造方法
定义处理数据的方法
@Component
public class ChangeLog<T> {
//俩data 一个是变更前基本数据,一个变更后基本数据单纯用来取变更后订单状态
public void record(T data,T oldData){
//获取所有字段
Field[] declaredFields = data.getClass().getDeclaredFields();
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(data));
JSONObject oldJson = JSON.parseObject(JSON.toJSONString(oldData));
for (Field field:declaredFields){
//循环获取字段获取指定注解
FieldValue annotation = field.getAnnotation(FieldValue.class);
if(ToolUtil.isNotEmpty(annotation)){
//获取注解的值
FieldEnum value = annotation.value();
//根据枚举一一获取就行了
if (FieldEnum.BUSINESS_NUM.equals(value)){
//假装JSONObject 有空值判断
changeRecordDto.setBusinessOrderNum(jsonObject.getString(field.getName()));
}else if{
//接下来一直套就行了
}
}
}
//记录数据
}
}
总结
稍微减少一下侵入代码,虽然跟在代码里面new一个对象传过来没什么区别
记得异常catch吃掉或者开个线程,不能影响业务代码