Spring AOP 实现——使用annotation、pointcut、aspect

1.annotation

  1. 注解@Interface,代表一种标记。常见的注解有@Override,@Deprecated,@SuppressWarnings。以及@Data。
  2. 注解的注解,成为元注解。常见元注解有:@Retention,@Target
  3. Retention有一个属性RetentionPolicy,包含3个值。
RetentionPolicy.SOURCE 不会保留在class,仅存为源文件。如@Data就是SOURCE
RetentionPolicy.CLASS 保留在class,但不被虚拟机加载。如@Builder
RetentionPolicy.RUNTIME 本文使用RUNTIME
  1. Target有多个枚举值。ElementType

本文的annotation

package com.tovan.hign.annocuts.aspect.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DayDayUp {
}

2.pointcut

pointcut有9种写法。

execute
within
this
target
args
@target
@within
@annotation
@args

本文使用@annotation实现pointcut

package com.tovan.hign.annocuts.aspect;

import org.aspectj.lang.annotation.Pointcut;

public class DayDayUpPointCut {

    @Pointcut("@annotation(com.tovan.hign.annocuts.aspect.annotation.DayDayUp)")
    public void dayDayUp() {

    }
}

3.aspect

使用时获取方法、参数、操作返回值等

package com.tovan.hign.annocuts.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;

@Aspect
@Slf4j
@Service
public class DayDayUpAspect {

    @Around("com.tovan.hign.annocuts.aspect.DayDayUpPointCut.dayDayUp()")
    public Object enhanceDayDayUp(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("正在经过切片增强。enhanceDayDayUp");
        // [1] 查看方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        log.info("方法 ={}", methodSignature.getMethod().getName());
        // [2] 查看参数名,参数值
        String[] argNames = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < argNames.length; i++) {
            log.info("参数 {} = {}", argNames[i], args[i]);
        }
        // [3] 选择操作或者不操作,然后进行返回
        return joinPoint.proceed();
    }
}

4.controller

controller调用

package com.tovan.hign.annocuts.web;

import com.tovan.hign.annocuts.aspect.annotation.DayDayUp;
import com.tovan.hign.annocuts.vo.BaseRequest;
import com.tovan.hign.annocuts.vo.BaseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("aop")
@Slf4j
public class AopController {

    @PostMapping("func")
    @DayDayUp
    public BaseResult funcDayDayUp(@RequestBody BaseRequest baseRequest, @RequestParam String currentTime) {
        log.info("baseRequest={},currentTime={}", baseRequest, currentTime);
        return BaseResult.success("WEB-操作成功。name=" + baseRequest.getName());
    }

}

5.console

控制台输出

2020-05-21 16:53:25.673  INFO 12120 --- [nio-8080-exec-3] c.t.hign.annocuts.aspect.DayDayUpAspect  : 正在经过切片增强。enhanceDayDayUp
2020-05-21 16:53:25.678  INFO 12120 --- [nio-8080-exec-3] c.t.hign.annocuts.aspect.DayDayUpAspect  : 方法 =funcDayDayUp
2020-05-21 16:53:28.495  INFO 12120 --- [nio-8080-exec-3] c.t.hign.annocuts.aspect.DayDayUpAspect  : 参数 baseRequest = BaseRequest(name=这是参数)
2020-05-21 16:53:28.496  INFO 12120 --- [nio-8080-exec-3] c.t.hign.annocuts.aspect.DayDayUpAspect  : 参数 currentTime = today
2020-05-21 16:53:28.496  INFO 12120 --- [nio-8080-exec-3] c.tovan.hign.annocuts.web.AopController  : baseRequest=BaseRequest(name=这是参数),currentTime=today
posted @ 2020-05-21 17:27  小拓同学  阅读(3295)  评论(0编辑  收藏  举报