SpringBoot 中aop整合方法执行日志

  今天事情不多, 处理完手中的事边想着捣鼓一下AOP, 着手开始写才发现, 多久不用, 自己已经忘得差不多了, 捣鼓半天之后, 慢慢整出这个小demo,以便于以后查阅回顾

 

1 .先创建一个注解, 用来作为AOP的切入点

  

/**
 * @author RYH
 * @description 日志标注
 * @date 2019/10/11
 **/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
    String value() default "";
}

 

2 .创建切面类, 以实现切面的通知

 

/**
 * @author RYH
 * @description aa
 * @date 2019/10/11
 **/
@Aspect
@Component
public class AopAspect implements Ordered {

    // 本地异常日志记录对象
    private static final Logger logger = LoggerFactory.getLogger(AopAspect.class);

    @Pointcut("@annotation(com.ryh.qtalk.annotation.SystemLog)")
    public void methodPointCut() {
    }

    @Before("methodPointCut()")
    public void beforeCut(JoinPoint point) {
        String name = point.getSignature().getName();
        logger.info("方法 {} 执行开始...............",name);
    }

    @Around("methodPointCut()")
    public Object printLog(ProceedingJoinPoint point) {
        String name = point.getSignature().getName();
        try {

            Class targetClass = point.getTarget().getClass();
            Method[] methods = targetClass.getMethods();
            for (int i = 0; i < methods.length; i++) {
                if (name.equals(methods[i].getName())) {
                    SystemLog annotation = methods[i].getAnnotation(SystemLog.class);
                    if (annotation != null) {
                        String value = annotation.value();
                        logger.info("SystemLog的值为:{}", value);
                    }
                }
            }

            long begin = System.currentTimeMillis();
            Object proceed = point.proceed();
            long end = System.currentTimeMillis();
            long time = end - begin;
            logger.info("执行{}方法成功, 执行时长{} ms", name, time);
            return proceed;
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
        }
        return new Object();
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

 

 

  这里定义的切点是放在注解上, 这样就只需要在要用到的接口方法上加上注解就行. 当然, 像是全局需要处理的, 就可以直接将切面放在controller,层或者service层, 在pointCut("execution(* com.ryh.qtalk.controller.*)")就行

 

我这里只是为了试验,只用到了前置通知(@before)和环绕通知(@around) 其他的也还有后置通知(@after), 然后再在需要通知切入的方法上加上注解@SystemLog就行

 

@SystemLog("hello")
    @RequestMapping("hello")
    public String hello() {
        List users = userDao.selectList(null);
        System.out.println(users);
        return "hello World";
    }

然后浏览器中访问这个controller的方法, 系统就会进入切面打印日志

 

这样一个初步的系统日志demo就搭建完成了, 想要别的功能也可以在里面进行添加.

 

你可能感兴趣的