简介
说明
本文介绍Spring(SpringBoot)的AOP的用法:自定义注解,在Controller的方法上使用此注解,然后在AOP中获得注解的相关信息。
本文使用@Around。
基础代码
项目结构、pom.xml、公共代码等与此文一样:Spring之AOP-将方法上的注解做为切点(用@Before) – 自学精灵
写法1:入参只有ProceedingJoinPoint
@Around入参只写ProceedingJoinPoint,有返回值。这个返回值会作为Controller数据返回回去。
AOP代码
package com.example.demo.aspect; import com.example.demo.annotation.OperationLog; import com.example.demo.common.util.JsonUtil; import com.example.demo.entity.User; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * Around结合方法注解获得操作日志 */ @Aspect @Component public class OperationLogAspectByAround { // 切点表达式,表示加了OperationLog注解的都是切点,路径是自定义注解的全路径 @Pointcut("@annotation(com.example.demo.annotation.OperationLog)") //多个切点时可指定优先级 // @Order(1) public void pointcut() { } //有ProceedingJoinPoint无注解类,有返回值 @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("################## around 进入 ##################"); MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); System.out.println("--------------------- 方法信息 ---------------------"); System.out.println("joinPoint.getTarget().toString() : " + joinPoint.getTarget().toString()); System.out.println("methodSignature.getName() : " + methodSignature.getName()); System.out.println("method.getName() : " + method.getName()); System.out.println("method.getReturnType().getName() : " + method.getReturnType().getName()); System.out.println("--------------------- 入参数据 ---------------------"); Object[] objects = joinPoint.getArgs(); System.out.println(JsonUtil.toJson(objects)); System.out.println("--------------------- 真正执行 ---------------------"); Object object = joinPoint.proceed(); System.out.println("--------------------- 执行结果 ---------------------"); System.out.println(JsonUtil.toJson(object)); System.out.println("--------------------- 注解数据 ---------------------"); OperationLog operationLog = method.getAnnotation(OperationLog.class); System.out.print("type: " + operationLog.type()); System.out.println("\tdesc: " + operationLog.desc()); return object; } }
测试
1.测试添加接口
后端结果
################## around 进入 ################## --------------------- 方法信息 --------------------- joinPoint.getTarget().toString() : com.example.demo.controller.UserController@3bfbf09e methodSignature.getName() : testAdd method.getName() : testAdd method.getReturnType().getName() : com.example.demo.entity.User --------------------- 入参数据 --------------------- [{"id":12,"userName":"Tony","note":"abc"}] --------------------- 真正执行 --------------------- --------------------- 执行结果 --------------------- {"id":12,"userName":"Tony","note":"abc"} --------------------- 注解数据 --------------------- type: 添加 desc: 添加数据
2.测试修改接口
后端结果
################## around 进入 ################## --------------------- 方法信息 --------------------- joinPoint.getTarget().toString() : com.example.demo.controller.UserController@3bfbf09e methodSignature.getName() : testUpdate method.getName() : testUpdate method.getReturnType().getName() : com.example.demo.entity.User --------------------- 入参数据 --------------------- [{"id":11,"userName":"Peter","note":"hello"}] --------------------- 真正执行 --------------------- id = 11 userName = Peter note = hello --------------------- 执行结果 --------------------- {"id":11,"userName":"Peter","note":"hello"} --------------------- 注解数据 --------------------- type: 更新 desc: 更新数据
写法2:入参为ProceedingJoinPoint + 注解类
@Around入参为ProceedingJoinPoint + 注解类,有返回值。这样就不用写@PointCut了,返回值会作为Controller数据返回回去。
AOP代码
package com.example.demo.aspect; import com.example.demo.annotation.OperationLog; import com.example.demo.common.util.JsonUtil; import com.example.demo.entity.User; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * Around结合方法注解获得操作日志 */ @Aspect @Component public class OperationLogAspectByAround { // 有ProceedingJoinPoint和注解类,有返回值。这样就不用写@Pointcut了 @Around("@annotation(operationLog)") public Object around(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable { System.out.println("################## around 进入 ##################"); MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); System.out.println("--------------------- 方法信息 ---------------------"); System.out.println("joinPoint.getTarget().toString() : " + joinPoint.getTarget().toString()); System.out.println("methodSignature.getName() : " + methodSignature.getName()); System.out.println("method.getName() : " + method.getName()); System.out.println("method.getReturnType().getName() : " + method.getReturnType().getName()); System.out.println("--------------------- 入参数据 ---------------------"); Object[] objects = joinPoint.getArgs(); System.out.println(JsonUtil.toJson(objects)); System.out.println("--------------------- 真正执行 ---------------------"); Object object = joinPoint.proceed(); System.out.println("--------------------- 执行结果 ---------------------"); System.out.println(JsonUtil.toJson(object)); System.out.println("--------------------- 注解数据 ---------------------"); System.out.print("type: " + operationLog.type()); System.out.println("\tdesc: " + operationLog.desc()); return object; } }
测试
1. 测试添加接口
后端结果
################## around 进入 ################## --------------------- 方法信息 --------------------- joinPoint.getTarget().toString() : com.example.demo.controller.UserController@19e107d7 methodSignature.getName() : testAdd method.getName() : testAdd method.getReturnType().getName() : com.example.demo.entity.User --------------------- 入参数据 --------------------- [{"id":11,"userName":"Tony","note":"cccc"}] --------------------- 真正执行 --------------------- --------------------- 执行结果 --------------------- {"id":11,"userName":"Tony","note":"cccc"} --------------------- 注解数据 --------------------- type: 添加 desc: 添加数据
测试2:测试修改接口
后端结果
################## around 进入 ################## --------------------- 方法信息 --------------------- joinPoint.getTarget().toString() : com.example.demo.controller.UserController@19e107d7 methodSignature.getName() : testUpdate method.getName() : testUpdate method.getReturnType().getName() : com.example.demo.entity.User --------------------- 入参数据 --------------------- [{"id":32,"userName":"Peter","note":"hi"}] --------------------- 真正执行 --------------------- id = 32 userName = Peter note = hi --------------------- 执行结果 --------------------- {"id":32,"userName":"Peter","note":"hi"} --------------------- 注解数据 --------------------- type: 更新 desc: 更新数据
请先
!