简介
说明
本文介绍Spring(SpringBoot)的AOP的用法:自定义注解,在Controller的方法上使用此注解,然后在AOP中获得注解和方法的相关信息。
本文使用@Before。
测试
访问测试页面:http://localhost:8080/doc.html
测试1:添加
后端结果
------------------ 方法信息 ------------------ joinPoint.getTarget().toString() : com.example.demo.controller.UserController@4671b282 methodSignature.getName() : testAdd method.getName() : testAdd method.getReturnType().getName() : com.example.demo.entity.User ------------------ 注解数据 ------------------ type: 添加 desc: 添加数据 ------------------ 入参数据 ------------------ User(id=123, userName=Tony, note=abc) id是:123; 名字是:Tony; 备注是:abc #################################################
测试2:更新
后端结果
------------------ 方法信息 ------------------ joinPoint.getTarget().toString() : com.example.demo.controller.UserController@4671b282 methodSignature.getName() : testUpdate method.getName() : testUpdate method.getReturnType().getName() : com.example.demo.entity.User ------------------ 注解数据 ------------------ type: 更新 desc: 更新数据 ------------------ 入参数据 ------------------ User(id=1, userName=Pepper, note=2) id是:1; 名字是:Pepper; 备注是:2 ################################################# id = 1 userName = Pepper note = 2
代码
创建工程
自定义注解类
package com.example.demo.annotation; import java.lang.annotation.*; @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface OperationLog { //操作的类型,添加,更新,删除 String type() default "add"; //操作描述 String desc() default ""; }
业务代码
Controller
package com.example.demo.controller; 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.*; @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; } }
Entity
package com.example.demo.entity; import lombok.Data; @Data public class User { private Integer id; private String userName; private String note; }
Service
package com.example.demo.service; import com.example.demo.entity.User; public interface UserService { public void printUser(User user); }
package com.example.demo.service.impl; import com.example.demo.entity.User; import com.example.demo.service.UserService; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService { @Override public void printUser(User user) { if (user == null) { throw new RuntimeException("检查用户参数是否为空"); } System.out.print("id = " + user.getId()); System.out.print("\t userName = " + user.getUserName()); System.out.println("\t note = " + user.getNote()); } }
启动类
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoSpringaopSimpleApplication { public static void main(String[] args) { SpringApplication.run(DemoSpringaopSimpleApplication.class, args); } }
AOP(核心)
@Around入参为ProceedingJoinPoint + 注解类,有返回值。这样就不用写@PointCut了,返回值会作为Controller数据返回回去。
package com.example.demo.aspect; import com.example.demo.annotation.OperationLog; import com.example.demo.entity.User; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * Before结合方法的注解获得操作日志 */ @Aspect @Component public class OperationLogAspectByBefore { //有ProceedingJoinPoint无注解类,有返回值 @Before("@annotation(operationLog)") public void before(JoinPoint joinPoint, OperationLog operationLog) throws Throwable { 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("------------------ 注解数据 ------------------"); System.out.print("type: " + operationLog.type()); System.out.println("\tdesc: " + operationLog.desc()); 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("#################################################"); } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo_SpringAOP</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo_SpringAOP</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
请先
!