Spring AOP 实现——使用annotation、pointcut、aspect
1.annotation
- 注解@Interface,代表一种标记。常见的注解有@Override,@Deprecated,@SuppressWarnings。以及@Data。
- 注解的注解,成为元注解。常见元注解有:@Retention,@Target
- Retention有一个属性RetentionPolicy,包含3个值。
RetentionPolicy.SOURCE 不会保留在class,仅存为源文件。如@Data就是SOURCE
RetentionPolicy.CLASS 保留在class,但不被虚拟机加载。如@Builder
RetentionPolicy.RUNTIME 本文使用RUNTIME
- 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