自定义注解 @AddUpdateLog
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AddUpdateLog {
}
自定义用于成员属性的注解@FieldInterface,作用稍后便知
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInterface {
String name() default "";
String convertField() default "";
}
原业务代码:
@Override
@AddUpdateLog
public ItemResult<Long> saveOrUpdateProcess(Request<ProcessFormDTO> request) {
Long result = null;
if (request.getData().getId() != null) {
processBiz.updateProcess(request.getData());
result = request.getData().getId();
} else {
ProcessFormDTO data = request.getData();
data.setCreateManager(request.getActionInfo().getUserId().longValue());
data.setCreateManagerName(request.getActionInfo().getNickname());
result = processBiz.createProcess(request.getData());
}
return new ItemResult<>(result);
}
其中入参属性:
public class ProcessFormDTO implements Serializable {
private Long id;
@FieldInterface(name = "申请流程")
private String processName;
@FieldInterface(name = "申请流程说明")
private String description;
private Long categoryId;
@FieldInterface(name = "审核类型")
private String categoryName;
@FieldInterface(name = "审核流程说明",convertField = "isCallback")
private Byte processType;
private Long createManager;
@FieldInterface(name = "创建人")
private String createManagerName;
private Long ownerManager;
@FieldInterface(name = "归属人")
private String ownerManagerName;
private Long ownerGroup;
@FieldInterface(name = "归属人组织")
private String ownerGroupName;
}
AOP核心代码:
/**
* 审核流程日志记录
*
* @author
*/
@Aspect
@Component
public class AuditLog {
private Logger logger = LoggerFactory.getLogger(AuditLog.class);
@Resource
private IAuditProcessMapper auditProcessMapperSlave;
@Resource
private ILogBiz logBiz;
/**
* 日志记录切入点
*/
// @Pointcut("execution(* com.ipr.biz.impl.ProcessBizImpl.updateProcess(..))")
@Pointcut("@annotation(com.ipr.audit.aop.AddUpdateLog)")
public void doLog() {
}
/**
* 后置通知
*/
@AfterReturning("doLog()")
public void after(JoinPoint point) throws Exception {
AuditLogDO auditLogDO = new AuditLogDO();
// 接口请求参数
Request args = (Request) point.getArgs()[0];
ActionInfo actionInfo = args.getActionInfo();
String operator = "SYSTEM";
Integer operatorId = 0;
if (!Objects.isNull(actionInfo)) {
operator = actionInfo.getNickname();
operatorId = actionInfo.getUserId();
}
auditLogDO.setOperatorId(operatorId.longValue());
auditLogDO.setOperatorName(operator);
// 变更详情
StringBuffer changeDetail = new StringBuffer(operator);
Field[] fields = null;
Object original = new Object();
if (args.getData() instanceof ProcessFormDTO) {
ProcessFormDTO arg = (ProcessFormDTO) args.getData();
AuditProcessDO auditProcessDO = ProcessConvert.fromProcessFormDTO(arg);
auditLogDO.setProcessId(auditProcessDO.getProcessId());
original = auditProcessMapperSlave.getAuditProcessByProcessId(auditProcessDO.getProcessId());
Class<? extends ProcessFormDTO> cls = arg.getClass();
fields = cls.getDeclaredFields();
} else if (...) {
...
}
assert fields != null;
for (Field f : fields) {
// 判断属性上是否上存在注解
boolean annotationPresent = f.isAnnotationPresent(FieldInterface.class);
f.setAccessible(true);
String fName = f.getName();
Object newValue = f.get(args.getData());
if (annotationPresent && newValue != null) {
System.out.println("属性名:" + fName + " 属性值:" + newValue);
FieldInterface fieldDescription = f.getAnnotation(FieldInterface.class);
// 获取注解值
String nameStr = fieldDescription.name();
String convertField = fieldDescription.convertField();
System.out.println(nameStr);
// 反射获取旧值
String getLetters = "";
if (StringUtils.isEmpty(convertField)) {
getLetters = fName.substring(0, 1).toUpperCase() + fName.substring(1);
} else {
getLetters = convertField.substring(0, 1).toUpperCase() + convertField.substring(1);
}
String getter = "get" + getLetters;
Method method = original.getClass().getMethod(getter);
Object value = method.invoke(original);
if (value instanceof Boolean) {
changeDetail.append("将").append(nameStr).append("由:\"").append(value).append("\"变更为:\"").append(newValue.equals(1)).append("\";\n");
} else {
changeDetail.append("将").append(nameStr).append("由:\"").append(value).append("\"变更为:\"").append(newValue).append("\";\n");
}
}
}
System.out.println(changeDetail);
auditLogDO.setOperateDetail(changeDetail.toString());
// mysql入库
addLogs(auditLogDO);
System.out.println("==============监听到更新流程===============");
System.out.println("==============更新流程====================");
System.out.println("==============流程=======================");
System.out.println("==============程=========================");
}
/**
* 环绕通知
*/
// @Around("doLog()")
public void around(ProceedingJoinPoint point) {
Object arg = null;
System.out.println("************* 环绕前..... *************");
System.out.println(point);
//得到参数
Object[] args = point.getArgs();
System.out.println("args=> " + Arrays.toString(args));
System.out.println(args[0] instanceof ProcessFormDTO);
if (args[0] instanceof ProcessFormDTO) {
ProcessFormDTO dto = (ProcessFormDTO) args[0];
System.out.println(JSON.toJSONString(dto.getId()));
}
// 得到切入点的类型
String kind = point.getKind();
System.out.println("kind => " + kind);
// 切入点 得到被增强方法的方法签名
MethodSignature methodSignature = (MethodSignature) point.getSignature();
// 方法名 到被增强方法的方法
Method method = methodSignature.getMethod();
System.out.println("method => " + method);
// 方法名 到被增强方法的方法 上面的注解
Signature signature = point.getSignature();
String name = signature.getName();
Class declaringType = signature.getDeclaringType();
int modifiers = signature.getModifiers();
String declaringTypeName = signature.getDeclaringTypeName();
System.out.println(" name => " + name + "\\\n declaringType => "
+ declaringType + "\\\n modifiers => " + modifiers + "\\\n declaringTypeName => " + declaringTypeName);
System.out.println("signature => " + signature);
// 得到目标
Object target = point.getTarget();
System.out.println("target => " + target);
System.out.println("************* 环绕后 *************");
}
/**
* 日志表新增记录
*
* @param auditLogDO
*/
private void addLogs(AuditLogDO auditLogDO) {
// Request<AuditLogDO> request = new Request<>(auditLogDO);
int i = logBiz.insertAuditLog(auditLogDO);
System.out.println(i);
}
}