上一篇文章我们讲解了Spring AOP是一个基于面向切面编程的框架,用于将某方面具体问题集中处理,通过代理对象来进行传递,但使用原生Spring AOP实现统一的拦截是非常繁琐的。而在本节,我们将使用一种简单的方式进行统一功能处理,具体如下:
- 统一用户登录权限验证
- 统一数据格式返回
- 统一异常处理
目录
0、我们先来回顾⼀下最初用户登录验证的实现方法:
@RestController
@RequestMapping("/user")
public class UserController {
/**
* 某⽅法 1
*/
@RequestMapping("/m1")
public Object method(HttpServletRequest request) {
// 有 session 就获取,没有不会创建
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("userinfo") != null) {
// 说明已经登录,业务处理
return true;
} else {
// 未登录
return false;
}
}
/**
* 某⽅法 2
*/
@RequestMapping("/m2")
public Object method2(HttpServletRequest request) {
// 有 session 就获取,没有不会创建
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("userinfo") != null) {
// 说明已经登录,业务处理
return true;
} else {
// 未登录
return false;
}
}
// 其他⽅法...
}
从上述代码可以看出,每个⽅法中都有相同的⽤户登录验证权限,它的缺点是:
1. 每个⽅法中都要单独写⽤户登录验证的⽅法,即使封装成公共⽅法,也⼀样要传参调⽤和在⽅法中进⾏判断。
2. 添加控制器越多,调⽤⽤户登录验证的⽅法也越多,这样就增加了后期的修改成本和维护成本。
3. 这些⽤户登录验证的⽅法和接下来要实现的业务⼏何没有任何关联,但每个⽅法中都要写⼀遍。
一、统一用户登录权限验证
1.1 使用原生Spring AOP 实现统一拦截
我们上一篇文章讲解了原生AOP:【Spring】Spring AOP 初识及实现原理解析
以使用原生 Spring AOP 来实现⽤户统⼀登录验证为例, 主要是使用前置通知和环绕通知实现的,具体实现如下:
package com.example.demo.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component // 随着框架的启动而启动
@Aspect // 告诉框架我是一个切面类
public class UserAspect {
// 定义切点(配置拦截规则)
@Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
public void pointcut(){
}
@Before("pointcut()")
public void beforeAdvice(){
System.out.println("执行了前置通知~");
}
@After("pointcut()")
public void AfterAdvice(){
System.out.println("执行了后置通知~");
}
/**
* 环绕通知
* @param joinPoint
* @return
*/
@Around("pointcut()")
public Object aroundAdvice(ProceedingJoinPoint joinPoint){
System.out.println("进入了环绕通知~");
Object obj = null;
try {
obj = joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.pr