0%

Springboot实现aop切面案例

以前写过很多次Aop切面,基于xml的配置方式,最近要求对每个接口进行权限校验,而不是页面,因为无法避免某个人没有页面权限,但是知道接口的情况,也刚好整理一下。

1.引入依赖
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.编写LogAspect类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* @author zllwsy
* @Description
* @Date 2021/7/28 13:48
* @Created by zllwsy
*/
@Component
@Aspect
public class LogAspect {
//切入点表达式
@Pointcut("execution(* com.zl.aop.controller.*.*(..))")
public void aopCut(){

}

//前置通知,也就是在目标方法执行之前执行
@Before(value = "aopCut()")
public void before(JoinPoint joinPoint){
//获取目标方法的名称
String name = joinPoint.getSignature().getName();
System.out.println(name + "方法执行之前");
}

//后置通知,也就是方法执行之后,获取目标方法的返回值
@AfterReturning(value = "aopCut()",returning = "result")
public void afterReturning(JoinPoint joinPoint,Object result){
String name = joinPoint.getSignature().getName();
System.out.println(name + "方法执行之后," + ", 返回值为: " + result);
}

//异常通知,也就是当方法出现异常时,调用该方法
@AfterThrowing(value = "aopCut()",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
String name = joinPoint.getSignature().getName();
System.out.println(name + "方法执行之后," + "抛出异常: " + e);
}

//环绕通知,也就是可实现任意通知,可调用 proceedingJoinPoint.proceed() 方法使目标方法继续执行
@Around(value = "aopCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String name = joinPoint.getSignature().getName();
//获取方法传入的参数
Object[] args = joinPoint.getArgs();
//可在这里对方法进行处理,调用自定义注解
ZLAopCut declaredAnnotation = getDeclaredAnnotation(joinPoint);
//然后调用proceed继续执行方法
Object proceed = joinPoint.proceed();
System.out.println("around");
return proceed;
}

//自定义注解
public ZLAopCut getDeclaredAnnotation(ProceedingJoinPoint joinPoint)throws NoSuchMethodException {
// 获取方法名
String methodName = joinPoint.getSignature().getName();
// 反射获取目标类
Class<?> targetClass = joinPoint.getTarget().getClass();
// 拿到方法对应的参数类型
Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
// 根据类、方法、参数类型(重载)获取到方法的具体信息
Method objMethod = targetClass.getMethod(methodName, parameterTypes);
// 拿到方法定义的注解信息
ZLAopCut annotation = objMethod.getDeclaredAnnotation(ZLAopCut.class);
// 返回
return annotation;
}
}
3.编写自定义注解
1
2
3
4
5
6
7
8
9
10
11
/**
* @author zllwsy
* @Description
* @Date 2021/7/28 14:08
* @Created by zllwsy
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ZLAopCut {
String method();
}
4.编写controller
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @Description
* @Date 2021/7/28 14:12
* @Created by zllwsy
*/
@RestController
@RequestMapping("/aop")
public class AopController {
@GetMapping("/test")
public String test() {
return "执行aop";
}
}
5.执行结果
image-20210728142925032
6.总结

​ 可适当根据自己的需求决定要加入哪些部分,自定义注解配合Around能够灵活的做一些操作,比如权限校验,接口权限等等。

----------本文结束感谢您的阅读----------