普通的MVC架构,Controller层是api的入口,现在想对每一个api的入参和返回值打印日志,用aspect 来实现很是方便。

       本文侧重实践,概念层面就不在陈述了。

 

第一步:自定义一个打印日志的注解

/**
 * 自定义打印日志的注解
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServiceLog {

}

 这里对@Retention 和 @Target做一下说明。

@Retention属于元注解(元注解的作用就是负责注解其他注解,有@Retention/@Target/@Documented/@Inherited),

@Retention用于定于注解的生命周期,即在什么时期时期生效,有如下三个值:

1、RetentionPolicy.SOURCE:存在源码级,编译时就会被忽略

2、RetentionPolicy.CLASS:存在于编译期,即class中会有

3、RetentionPolicy.RUNTIME:在jvm运用时存在,能被读取到和使用

 

@Target是注解用在什么地方,是某个包、还是类、方法、构造器等等

ElemenetType.METHOD:方法

ElemenetType.PACKAGE :包

ElemenetType.PARAMETER :参数

等等

 

第二步:新增一个切面类,里面提供切入点方法和调用切点方法时机的方法

@Aspect
@Component
public class WebLogAscept
{
    /**
     * 以自定义 @WebLog 注解为切点
     */
//    @Pointcut("@annotation(com.tm.backend.newapproval.aspect.WebLog)") // 扫描有WebLog注解的方法
    @Pointcut("execution(* com.tm.backend.approval.endpoint.*.*(..))") // 扫描包下所有方法
    public void webLog()
    {
    }

    /**
     * 切点之前
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable
    {
        // 开始打印请求日志
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        System.out.println("方法名:"+signature.getName()+". 入参:"+joinPoint.getArgs());
    }

    /**
     * 环绕
     */
    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
    {
        Object result = proceedingJoinPoint.proceed();
        System.out.println("返回值:"+result);
        return result;
    }

}

 

总结:重点是自定义注解并且添加了切点后,这些切点在方法的什么地方用,并且获取相应的属性

 

posted on 2021-04-19 16:13  天马行空的秋意  阅读(545)  评论(0编辑  收藏  举报