简介
说明
本文介绍Spring(SpringBoot)的AOP的用法:自定义注解,在Controller的类上使用此注解,然后在AOP中获得注解和方法的相关信息。
本文使用@Before。
方案介绍
AOP可将切点设为注解类,例如,若想控制Controller,只需切@Controller,方法有:
法1:@Before或@Around,结合@within
@Before("@within(controller)") public void before(JoinPoint joinPoint, Controller controller)
法2:@Pointcut结合@within
@Pointcut("@within(org.springframework.stereotype.Controller)")
基础代码
项目结构、pom.xml、公共代码等与此文一样:Spring之AOP-将方法上的注解做为切点(用@Before) – 自学精灵
AOP代码
package com.example.demo.aspect; import com.example.demo.annotation.ApiLog; import com.example.demo.annotation.OperationLog; import com.example.demo.entity.User; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * Before结合类上的注解获得操作日志 */ @Aspect @Component public class ApiLogAspectByBefore { //有ProceedingJoinPoint,有注解类 @Before("@within(apiLog)") public void before(JoinPoint joinPoint, ApiLog apiLog) { 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("------------------ 类的ApiLog注解数据 ------------------"); System.out.println("tag: " + apiLog.tag()); System.out.println("------------------ 类的Api注解数据 ------------------"); Class<?> aClass = method.getDeclaringClass(); if (aClass.isAnnotationPresent(Api.class)) { String[] tags = aClass.getAnnotation(Api.class).tags(); String value = aClass.getAnnotation(Api.class).value(); String tagJoin = String.join("+", tags); System.out.println("tags:" + tagJoin + "; value:" + value); } System.out.println("------------------ 方法注解数据 ----------------"); if (method.isAnnotationPresent(ApiOperation.class)) { System.out.println("操作为:" + method.getAnnotation(ApiOperation.class).value()); } System.out.println("------------------ 入参数据 ------------------"); Object[] objects = joinPoint.getArgs(); for (Object o : objects) { System.out.println(o); if (o instanceof User) { System.out.println("id是:" + ((User) (o)).getId() + "; 名字是:" + ((User) (o)).getUserName() + "; 备注是:" + ((User) (o)).getNote()); } } System.out.println("#################################################"); } }
业务代码
package com.example.demo.controller; import com.example.demo.annotation.ApiLog; import com.example.demo.annotation.OperationLog; import com.example.demo.entity.User; import com.example.demo.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @ApiLog(tag = "用户接口") @Api(tags = "用户") @RequestMapping("/user") @RestController public class UserController { @Autowired private UserService userService; @ApiOperation("打印数据") @GetMapping("print") public User testPrint(User user) { userService.printUser(user); return user; } @ApiOperation("添加数据") @PostMapping("add") @OperationLog(type = "添加", desc = "添加数据") public User testAdd(User user) { return user; } @ApiOperation("更新数据") @PostMapping("update") @OperationLog(type = "更新", desc = "更新数据") public User testUpdate(User user) { userService.printUser(user); return user; } @ApiOperation("删除数据") @PostMapping("delete") public void delete(User user) { } }
测试
测试1:更新操作(有返回值)
后端结果:
------------------ 方法信息 ------------------ joinPoint.getTarget().toString() : com.example.demo.controller.UserController@4091a89b methodSignature.getName() : testUpdate method.getName() : testUpdate method.getReturnType().getName() : com.example.demo.entity.User ------------------ 类的ApiLog注解数据 ------------------ tag: 用户接口 ------------------ 类的Api注解数据 ------------------ tags:用户; value: ------------------ 方法注解数据 ---------------- 操作为:更新数据 ------------------ 入参数据 ------------------ User(id=111, userName=Peter, note=bbb) id是:111; 名字是:Peter; 备注是:bbb ################################################# id = 111 userName = Peter note = bbb
测试2:删除操作(无返回值)
后端结果:
------------------ 方法信息 ------------------ joinPoint.getTarget().toString() : com.example.demo.controller.UserController@4091a89b methodSignature.getName() : delete method.getName() : delete method.getReturnType().getName() : void ------------------ 类的ApiLog注解数据 ------------------ tag: 用户接口 ------------------ 类的Api注解数据 ------------------ tags:用户; value: ------------------ 方法注解数据 ---------------- 操作为:删除数据 ------------------ 入参数据 ------------------ User(id=12, userName=Tony, note=aaa) id是:12; 名字是:Tony; 备注是:aaa #################################################
请先
!