springboot项目中使用注解的方式实现
首先:编写一个对于操作方法进行日志记录的注解
package com.springtest.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnonation {
/**
* 操作类型,方便记录
* @return String
*/
String value() default "";
}
然后,注解的切面配置
这里采用了两中切面通知:
分别是返回通知和异常通知,注解中的参数方便在返回通知或者异常通知中处理操作类型(方法做了什么操作)
返回通知是方法正常执行时候会进入的通知方法,可以通过对方法返回值的信息判断方法执行结果是或否成功
异常通知是方法执行产生异常进入的方法
@Aspect @Component public class LogInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(OperationLogInterceptor.class); /** * 定义切入点为 带有 LogAnnonation 注解的 */ @Pointcut("@annotation(com.trendytech.tapp.annotation.LogAnnonation)") private void param() { } /** * 返回通知(正常返回) */ @AfterReturning(value = "param()", returning = "result") public void afterReturning(JoinPoint joinPoint, ResponseData result) throws Throwable { String operationResult = "失败"; if (result.getCode() == ResponseCode.SUCCESS) { operationResult = "成功"; } dealDifferentLogs(joinPoint, operationResult); } /** * 异常通知(失败操作) */ @AfterThrowing(value = "param()", throwing = "exception") public void afterThrowing(JoinPoint joinPoint, Exception exception) throws Throwable { dealDifferentLogs(joinPoint, "失败"); LOGGER.error("OperationLogInterceptor afterThrowing exception catch ...", exception); } }
如何使用
举个栗子:
只需要在操作的方法上面加上方法的注解和注解携带的参数值即可
@OperationLog("MODIFY_VIRTUAL") @RequestMapping(value = "/{id}", method = RequestMethod.PUT) public ResponseData<VirtualVo> modifyVirtualServer(@PathVariable("id") String id, @RequestBody VirtualVo virtualServer) { return virtualServerService.modify(id, virtualServer); }
备注:使用这种方式手机日志还需要支持一个方法,从注解中取得注解value从而判断这个方法的操作类型是什么,方法如下
获取注解定义的参数----就是上面代码中的
@OperationLog("MODIFY_VIRTUAL")
/** * 获取自定义注解的参数 * * @param joinPoint joinPoint * @return LogAnnotation 注解 * @throws ClassNotFoundException ClassNotFoundException */ public LogAnnotation getAnnotationParam(JoinPoint joinPoint) throws ClassNotFoundException { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { return method.getAnnotation(OperationLog.class); } } return null; }
获取注解方法中某个参数的值
/** * 通过反射机制 获取被切参数名以及参数值 * * @param joinPoint joinPoint * @return 参数集合 * @throws NotFoundException NotFoundException * @throws ClassNotFoundException ClassNotFoundException */ public static Map<String, Object> getMethodParams(JoinPoint joinPoint) throws NotFoundException, ClassNotFoundException { //参数名称 String[] paramName = ((CodeSignature) joinPoint.getSignature()).getParameterNames(); //参数值 Object[] paramValue = joinPoint.getArgs(); Map<String, Object> map = new HashMap<>(); for (int i = 0; i < paramName.length; i++) { try { map.put(paramName[i], paramValue[i]); } catch (Exception e) { LOGGER.error("get method params error!", e); } } return map; }
备注:使用方法为
getMethodParams(joinPoint).get(id); 获取方法中的id参数的值
个人总结 如果不正确或者不理解之处欢迎留言指出