My Avatar

licaibo

在JDK改来改去!

SpringAOP自定义注解记录日志

2017年07月06日 星期四, 发表于 海南 海口

如果你对本文有任何的建议或者疑问, 可以在 这里给我提 Issues, 谢谢! :)

在项目开发中,通常我们会记录一些用户操作上的日志,主要有修改人、修改时间、修改内容等等,以便于后续的问题排查和分析。最近在开发时,刚好需要在用户操作时,记录相关日志。在参考了网上的方案后,决定使用自定义注解和AOP的方法。面向切面的编程,就算是记录日志出错了也不影响到主流程业务。

(1) 自定义注解

自定义注解用于标识需要拦截的方法,可以是主题和类型等,具体视情况而定

1
2
3
4
5
6
7
8
9
10
11
12
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Log {

    /** * 主题(新增或是修改) * @return */
    String item() default "";

    /** * 类型(用户信息修改等) * @return */
    String type() default "";

}

(2) 定义Spring AOP切面

Spring AOP提供了几种注解用于不同的场景。我的工程是SpringBoot项目,在这里选择了@AfterReturning,在方法执行完后再去执行,并且用@Async声明了该方法是异步的执行。 注:SpringBoot使用@Async需要在启动时加上@EnableAsync

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Aspect
@Component
public class LogAop {

private static final Logger logger=LoggerFactory.getLogger(LogAop.class);

    //声明AOP切入点,凡是使用了@Log的方法均被拦截
    @Pointcut("@annotation(com.lcb.demo.annotation.Log)")
    public void logPointcut() { }

    @Async
    @AfterReturning(pointcut = "logPointcut() && @annotation(log)",returning = "returnValue")
    public void afterFileOperate(JoinPoint joinPoint,
                                 Log log,
                                 Object returnValue) {
        logger.info("开始记录【{}】操作的日志信息",chargeIten);

        //获取注解的属性值
        String iten = log.item();
        String type = log.type();
        //获取拦截方法的参数
        Object[] objects = joinPoint.getArgs();

        //TODO 实现自己对日志记录的逻辑

        logger.info("结束记录【{}】操作的日志信息",chargeIten);

    }

}

(3) 在方法上声明@Log注解

1
2
3
4
5
6
@Log(item = "用户信息",type="修改")
public String testLog(String text) {
        return "abc";
    }