Aop实现登录校验
AI-摘要
Smith GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
了解更多
Aop实现登录校验
Smith这段代码完美地演示了我们刚才聊的 AOP(切面编程) 概念在真实项目里是怎么用的。你可以把它理解成奶茶店门口的 “安检员”。
这个安检员不参与做奶茶(业务逻辑),他只负责在顾客进门(调用方法)前,检查你有没有会员卡(Token)。
我们把它拆开揉碎,逐段翻译成“人话”。
🎯 一、代码整体身份:门禁切面
1 | // 1. 告诉Spring:这也是个受IoC管理的组件 |
@Aspect:关键标签,声明这个类是 AOP 的切面。Spring 看到这个标签,就会把这个类里的代码逻辑织入到你指定的方法上。@Component:把这个安检员交给 Spring 的 IoC 容器管理,这样安检员才能拿到钥匙(RedisComponent)。
🔪 二、切入点定义:这安检员站哪?
1 |
|
@Before:通知类型。表示在目标方法执行之前插一杠子。@annotation(...):切入点表达式。意思是:谁头上贴了@GlobalInterceptor这个标签,我就站在谁门口检查。
通俗比喻:
店长规定:凡是门口挂着 “需要会员” 牌子的房间(方法),安检员必须在顾客进去前拦一下。
🧩 三、方法体执行流程(安检步骤拆解)
1. 第一步:看清楚门牌上写的啥要求
1 | Method method = ((MethodSignature) point.getSignature()).getMethod(); |
- 作用:通过反射拿到方法上贴的那个注解对象。
- 目的:看看这个注解里的配置是什么。比如有的房间只是打个卡,有的房间必须验身。
2. 第二步:如果要求“必须登录”,就执行检查
1 | if (interceptor.checkLogin()) { |
这里调用了私有方法 checkLogin(),这是核心逻辑所在。
🔑 四、核心校验逻辑 checkLogin() 详解
这是安检员工作的具体内容:
1. 拿到顾客手里的小票(HttpServletRequest)
1 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
RequestContextHolder:Spring 提供的一个工具,让你在任何地方都能拿到当前这次 HTTP 请求的上下文。getHeader("token"):前端调用接口时必须在请求头里带上token(比如token: abc123),就像进门要刷卡。
2. 没带卡?直接拦下报错
1 | if (StringTools.isEmpty(token)) { |
- 如果请求头里没有
token字段,直接抛出业务异常CODE_901(通常代表“未登录”或“Token 失效”)。被拦下后,核心业务代码根本不会执行。
3. 去 Redis(后台数据库)验卡真伪
1 | TokenUserInfoDTO tokenUserInfoDto = redisComponent.getTokenInfo(token); |
- 用户登录成功后,后端会把用户信息(名字、ID)存在 Redis 里,Key 就是
token。 - 这里安检员拿着
token去 Redis 查:“有这个钥匙对应的记录吗?”
4. 开发环境彩蛋(免检通道)
1 | if (System.getProperty("dev") != null) { |
- 作用:方便程序员本地调试。
- 解释:如果启动参数加了
-Ddev(开发模式),安检员会假装你是个合法用户,直接给你生成一个虚拟身份塞进 Redis。这样你就不用每次重启项目都重新登录了。生产环境没有这个参数,这代码就不会执行。
5. 最终判决
1 | if (tokenUserInfoDto == null) { |
- Redis 里查不到用户信息?卡是假的!同样抛出 901 异常拦下。
💡 五、为什么说这是 AOP 的“最佳实践”?
假设你要写一个查询用户钱包的接口:
❌ 没有 AOP 的写法(痛苦):
1 | public Wallet getMyWallet() { |
✅ 有了这个 AOP 切面后的写法(优雅):
1 | // 贴个标签,完事! |
🧠 六、总结这段代码的运转逻辑图
- 用户请求
GET /user/wallet-> 携带 Header: token=xxx - Spring 拦截器机制 -> 发现方法上有
@GlobalInterceptor注解。 - 织入切面 -> 执行
GlobalOperationAspect.interceptorDo()。 - 切面逻辑:
- 拿 Token。
- Token 为空 -> 原地爆炸(报错901),业务代码不执行。
- Token 不为空 -> 查 Redis。
- Redis 无数据 -> 原地爆炸(报错901)。
- Redis 有数据 -> 放行。
- 放行后 -> 才执行真正的
getMyWallet()业务代码。
一句话总结这段代码的核心价值:
它把 登录校验 这种每个接口都要做的“脏活累活”,从业务代码中剥离出来,变成了一个独立的 切面组件。实现了 代码复用 和 业务逻辑解耦。这正是 AOP 的强大之处。



