4.springboot apo 实现权限注解 :https://blog.csdn.net/weixin_46899412/article/details/124887138 5.注解参数说明:https://blog.csdn.net/qiaoshan12138/article/details/115067111 6:向注解中传值: https://www.jianshu.com/p/0d7af1673249 (使用spel表达式)
1.先创建自定义注解类
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log { String value() default ""; int type() default 0; }
2.使用aop将注解作为切入点
@Component @Aspect @Slf4j public class LogAspect { private final LogService logService; ThreadLocal<Long> currentTime = new ThreadLocal<>(); public LogAspect(LogService logService) { this.logService = logService; } /** * 配置切入点 */ @Pointcut("@annotation(co.yixiang.modules.logging.aop.log.Log)") public void logPointcut() { // 该方法无方法体,主要为了让同类中其他方法使用此切入点 } /** * 配置环绕通知,使用在方法logPointcut()上注册的切入点 * * @param joinPoint join point for advice */ @Around("logPointcut()") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { Object result; currentTime.set(System.currentTimeMillis()); result = joinPoint.proceed(); Log log = new Log("INFO", System.currentTimeMillis() - currentTime.get()); currentTime.remove(); HttpServletRequest request = RequestHolder.getHttpServletRequest(); logService.save(getUsername(), StringUtils.getIp(RequestHolder.getHttpServletRequest()), joinPoint, log, getUid()); return result; } /** * 配置异常通知 * * @param joinPoint join point for advice * @param e exception */ @AfterThrowing(pointcut = "logPointcut()", throwing = "e") public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { Log log = new Log("ERROR", System.currentTimeMillis() - currentTime.get()); currentTime.remove(); log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes()); HttpServletRequest request = RequestHolder.getHttpServletRequest(); logService.save(getUsername(), StringUtils.getIp(RequestHolder.getHttpServletRequest()), (ProceedingJoinPoint) joinPoint, log, getUid()); } public String getUsername() { try { return SecurityUtils.getUsername(); } catch (Exception e) { return ""; } } public Long getUid() { try { return SecurityUtils.getUserId(); } catch (Exception e) { return 0L; } } }
3.上面使用到的logservice 中的save方法
@Override @Transactional(rollbackFor = Exception.class) public void save(String username, String ip, ProceedingJoinPoint joinPoint, co.yixiang.modules.logging.domain.Log log, Long uid) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Log aopLog = method.getAnnotation(Log.class); //获取目标方法上的@Log注解 // 方法路径 String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; StringBuilder params = new StringBuilder("{"); //参数值 Object[] argValues = joinPoint.getArgs(); //参数名称 String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); if (argValues != null) { for (int i = 0; i < argValues.length; i++) { params.append(" ").append(argNames[i]).append(": ").append(argValues[i]); } } // 描述 if (log != null) { log.setDescription(aopLog.value()); //获取目标方法上的注解的参数 如:@Log("查询Redis缓存") } //类型 0-后台 1-前台 log.setType(aopLog.type()); if (uid != null) { log.setUid(uid); } assert log != null; log.setRequestIp(ip); String loginPath = "login"; if (loginPath.equals(signature.getName())) { try { assert argValues != null; username = new JSONObject(argValues[0]).get("username").toString(); } catch (Exception e) { e.printStackTrace(); } } log.setAddress(StringUtils.getCityInfo(log.getRequestIp())); log.setMethod(methodName); log.setUsername(username); log.setParams(params.toString() + " }"); this.save(log); }