工作需求:在已有的项目中 增加操作日志功能, 要求 操作记录详细到 具体字段的修改,可指定具体需要记录的字段。
工作分三步走:
第一,增加自定义注解,确定拦截数据的格式。
第二:增加aop拦截器。
第三:业务代码。
第一,增加自定义注解,确定拦截数据的格式。
1.声明 @interface 类 。
2.:声明 注解应用于方法级别 @Target({ElementType.METHOD,ElementType.PARAMETER})
3.声明 注解 运行时可用 @Retention(RetentionPolicy.RUNTIME)
4.声明 业务需要的 三个参数,optionType 操作类型 optionModel 操作模块 optionContent 操作内容
示例注解格式:
@OptionLog(optionType = "update",optionModel = "feedBack",optionContent = "将[{contact}]的反馈状态修改为[{ctrlFlagName}],添加备注[{remarks}]")
/**
* todo:
* 类SysLog的功能描述:
* 系统日志注解
*/
@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
//@Documented
public @interface OptionLog {
String optionType() default "select";
String optionModel() default "";
String optionContent() default "";
}
第二:增加aop拦截器。
1.使用@Aspect 新建切面类。
@Component
@Aspect
public class OptionInterceptor
2.定义切点方法。@Pointcut
@Pointcut("execution (* com.jjjjj.hangzhou.pillow.dao..*.*(..))")
public void daoAspect(){
}
3.使用后置返回通知 @AfterReturning 确保本次操作完成后 ,记录日志操作。
@AfterReturning(value = "daoAspect()",returning = "returnValue")
public void doAfterReturn(JoinPoint joinPoint,Object returnValue)
第三:在aop通知中增加业务处理工作。
1.获取方法名,并通过spring获取注解,判断当前方法是否被注解。
Signature signature = joinPoint.getSignature(); //方法签名
Method method = ((MethodSignature)signature).getMethod();
//获取真正的带注解的方法
OptionLog optionLog = AnnotationUtils.findAnnotation(method,OptionLog.class);
if(!ObjectUtils.isEmpty(optionLog))
2.获取注解中的参数和方法中的参数,匹配修改自定义的日志格式。
//操作记录原始记录
StringBuffer optionDetails = new StringBuffer();
//返回参数
Object[] args = joinPoint.getArgs();
String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
//logger.info("args:"+args[0]);
//logger.info("argName:"+argNames[0]);
//logger.info("returnValue"+returnValue);
Class c3 = args[0].getClass();
Field[] fields = c3.getDeclaredFields();
if(optionLog.optionType().equals("update")) {
optionDetails.append("发生修改操作:[");
for(int x=0;x<fields.length;x++){
Field field = fields[x];
field.setAccessible(true);
String fieldName = field.getName();
String fieldValue = getFieldValue(field,args[0]); //获取参数值
if(!fieldName.equals("serialVersionUID") && !ObjectUtils.isEmpty(fieldValue)) {
System.out.println();
//System.out.println("属性名:" + fieldName + ",属性值:" + fieldValue);
optionDetails.append("{colume:"+fieldName+",newValue:"+fieldValue+"},");
}
}
optionDetails.append("]");
/**
* 后置返回通知
*/
@AfterReturning(value = "daoAspect()",returning = "returnValue")
public void doAfterReturn(JoinPoint joinPoint,Object returnValue){
try {
Signature signature = joinPoint.getSignature(); //方法签名
Method method = ((MethodSignature)signature).getMethod();
//获取真正的带注解的方法
OptionLog optionLog = AnnotationUtils.findAnnotation(method,OptionLog.class);
if(!ObjectUtils.isEmpty(optionLog)){
logger.info("后置返回通知,操作类型:" + optionLog.optionType() +",操作模块:"+ optionLog.optionModel());
//操作记录原始记录
StringBuffer optionDetails = new StringBuffer();
//返回参数
Object[] args = joinPoint.getArgs();
String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
//logger.info("args:"+args[0]);
//logger.info("argName:"+argNames[0]);
//logger.info("returnValue"+returnValue);
Class c3 = args[0].getClass();
Field[] fields = c3.getDeclaredFields();
if(optionLog.optionType().equals("update")) {
optionDetails.append("发生修改操作:[");
for(int x=0;x<fields.length;x++){
Field field = fields[x];
field.setAccessible(true);
String fieldName = field.getName();
String fieldValue = getFieldValue(field,args[0]);
if(!fieldName.equals("serialVersionUID") && !ObjectUtils.isEmpty(fieldValue)) {
System.out.println();
//System.out.println("属性名:" + fieldName + ",属性值:" + fieldValue);
optionDetails.append("{colume:"+fieldName+",newValue:"+fieldValue+"},");
}
}
optionDetails.append("]");
}else if(optionLog.optionType().equals("insert")) {
optionDetails.append("发生插入操作:[");
for(int x=0;x<fields.length;x++){
Field field = fields[x];
field.setAccessible(true);
String fieldName = field.getName();
String fieldValue = getFieldValue(field,args[0]);
if(!fieldName.equals("serialVersionUID") && !ObjectUtils.isEmpty(fieldValue)) {
optionDetails.append("{colume:"+fieldName+",newValue:"+fieldValue+"},");
}
}
optionDetails.append("]");
}else if(optionLog.optionType().equals("delete")) {
optionDetails.append("发生删除操作:[");
for(int x=0;x<args.length;x++){
if(ObjectUtils.isEm