Springboot 实现Aop切面编程
1. 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.写切面方法
现在有个方法,
public List<User> getList() {
List<User> users = userMapper.selectList(null);
return users;
}
获取用户返回列表,返回有2条数据,现在要实现把这个数据进行改变
可以先写个自定义注解,加在上面这个方法上,然后切面的时候指定有这个注解的就切入
自定义注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAnnotation {
}
刚刚的方法上套上去注解
@UserAnnotation
public List<User> getList() {
List<User> users = userMapper.selectList(null);
return users;
}
开始写切面
@Pointcut里面写上"@annotation(com.example.printdemo.annotation.UserAnnotation)"
就是注解UserAnnotation的位置,相当于监控着这个注解,方法上有使用到这个注解的都会进入这个切面方法,也可以指定类方法的方式切入,我喜欢用注解的方法所以用这个
切入点表达式用于匹配特定的方法或者类,从而确定切面应该在何处应用。除了使用@annotation
来匹配注解的方法,还可以使用其他类型的切入点表达式,例如:
execution
:匹配方法的执行。within
:匹配在特定类或包中的所有方法。args
:匹配具有特定参数类型的方法。target
:匹配特定目标对象的方法。this
和bean
:匹配当前代理对象或特定Spring bean的方法。
@Around("userListAspect()") 这里用环绕方法,括号里面就是把@Pointcut的方法写上就行
@Aspect
@Component
public class UserListAspect {
@Pointcut("@annotation(com.example.printdemo.annotation.UserAnnotation)")
public void userListAspect() {}
@Around("userListAspect()")
public Object before(ProceedingJoinPoint pjp) throws Throwable {
// 执行原方法
Object result = pjp.proceed();
// 检查返回值是否为List类型
if (result instanceof List) {
List<User> users = (List<User>) result;
for (User user : users) {
System.out.println(user);
}
// 去掉第二个元素
users.remove(1);
return users;
}
return null;
}
@After("userListAspect()")
public void afterList() {
System.out.println("后置 执行");
}
}
这里我把返回值去掉了第二个元素,然后return出去,进行修改数据
这里可以做其它的,例如进入方法前的权限检查,方法执行时间,输出日志之类
现在用的是环绕切面
还有其他的:AOP提供了多种类型的通知,每种通知都有其特定的执行时机:
@Before
:在方法执行之前执行。@After
:在方法执行之后执行,无论方法是否成功。@AfterReturning
:在方法成功返回之后执行。@AfterThrowing
:在方法抛出异常之后执行。@Around
:在方法执行前后都执行,可以完全控制方法的执行过程。