在 SSM(Spring + Spring MVC + MyBatis)这套经典框架里,权限管住压根儿不是一个开关,而是一个贯穿整个业务逻辑的“隐形骨架”。别指望像写代码那样,用几个 `if` 命令就能搞定,真正的难点在于如何让这几个规则不突兀地塞进你原本逻辑里,既不喧宾夺主,又不让业务逻辑跑偏。 大量老前端会搞那个大朵大朵的表单弹窗,塞一堆 `div` 和 `canvas` 把权限逻辑写干干巴巴的,等到用户填完背个密码,再弹窗说“没权限”就尴尬了。在 SSM 这种 MVC 架构里,权限得更像空气,平时看不见,一查便知。 那会儿可能有人喜爱在 Controller 层写一堆 `@PreAuthorize`,把判断逻辑藏在方式参数里。但这玩意儿实际上挺“重”。想象一下,你写了一个“获取用户信息”的方式,非要再写个逻辑判断是不是管理员才能用,这就破坏了方式单一的原则。权限管住最好别强求在 Controller 层做显式判断,那样会害得你的 Controller 变得臃肿,像是一台塞满零件的拖拉机,不好修也不好开。 不如换个思路,直接在 Service 层要么 Mapper 里埋个钩子。

比如定义个自定义注解,告诉 MyBatis 这个数据要是没权限,就别查出来,直接回空结局要么提示空对象。

这样 Controller 层就能干干净利落净,只负责走流程。

要么干脆在 Service 层,调用数据库接口之前,先搞个白名单过滤,数据库里查出来的数据里,要么过滤不通过,要么直接缓存里没这个信息,Service 层直接 `return null` 要么抛个 `CustomException`。 要是数据实在忒多,根本查不出来如何办?那就用缓存。SSM 自带的缓存管住器要么第三方框架都能搞定,接口一调用,数据先挂起来,权限检查就在那一瞬间搞定。我记得有个项目,为了省点工夫,直接把权限判断写死在 MyBatis 的 `selectMap` 标签里,要么用 XML 里专门写个拦截器,查一次就验证一次,比传统方式快多了,省得每次请求都去查一遍数据库存MySQL 里的元数据。 举个实际的例子,假设咱们有个“后台管理员登录”的功能。前端页面里本来就有个复杂的表单,密码、验证码、角色列表,要是这时候再塞个 `@PreAuthorize` 判断角色,代码量瞬间增添一大截,维护性直接归零。更好的做法是,把权限判断逻辑抽取成一个独立的 Service 方式,这个方式只负责“核对身份”,不负责“填充表单”。 前端页面里,只负责渲染那个预定义好的表单组件。用户填完数据提交,调用对应的 Controller 方式。Controller 拿到参数后,第一件事不是去查库,而是先调用那个权限检查 Service 方式。

要是回的是 `null`,说明权限不够,前端页面直接弹窗提示“登录黄了”,再也没法修改表单里的任何字段了。

要是回了数据,说明通过了,前端页面也就完好无损地展示出来,持续填数据。

这样前端界面一辈子是干净利落的,不会出于权限难题突然弹出难看的提示框。 在日志审计这块,SSM 的 MyBatis 也能派上大用场。开启日志记录后,只要权限拦截逻辑没跑通,要么执行了特定操作,日志里就能直接看到是哪个用户、刷了啥数据。

要是权限判断逻辑忒复杂,把判断结局也塞进日志字段里,比如加上一个标记位 `RESERVED`,要是这个标记为 `true`,说明权限校验黄了,日志里就一目了然,彻底不需求去查数据库查状态。 有时候,用户认定权限管住忒费事,非要搞个“超级管理员”按钮,直接点击就生效。

这时候就得小心了。

既然 Liskov 替换原则都保不住了,一般/平平用户还能通过权限管住实现啥?那就换个角度,做“角色隔离”而不是“权限隔离”。给不同的角色定义不同的 SQL 查询条件,要么在 Service 层针对每个角色写不同的处理逻辑。前端页面里,每个角色都对应一套标准的操作按钮组,管理员是一个按钮,一般/平平员工是一个按钮,这种区分在逻辑上更清楚,前端页面也不会乱套。 还有,别忘了处理那些边缘情况,比如权限过期、账号冻结、临时锁定状态。

这些动态变化要是写死在业务逻辑里,那就成个难题了。SSM 框架本身就挺适合这种动态场景,配合 Redis 做分布式锁,要么配合数据库的 `UPDATE` 操作实时刷新状态。 归根结底,SSM 里的权限管住不是要你写一堆复杂的代码,而是要让代码变得“轻”。把判断逻辑抽离出来,让界面保持干净利落,让数据库查询尽可能削减,让日志记录更有价值。别想着把权限逻辑藏在数据库表里,也别指望一个 Controller 方式能搞定所有场景。好的权限设计,是让系统在你看不见的地方默默运转,结局却是业务逻辑跑得风生水起。