761 字
约 2 分钟
26
S27-J04 · AOP 与对象转换:代理、拦截、MapStruct

适用读者:被 setXXX 和"切面不生效"折磨的人。
前置:S07-B03(AOP 代理)。
覆盖旧文:381(260) 374(332) + 相关 = 766 点。
扩展点:E-S27-014(MapStruct 与反射拷贝的边界)。
上一篇:S27-J03 · 验证码与风控:滑块设计与实现
下一篇:S27-J05 · 架构演进。


1. 一句话结论

AOP 解决"横切逻辑"(日志/事务/权限),对象转换解决"样板赋值"——两者都在"减少重复代码",但机制完全不同:一个是代理,一个是编译期生成。

手段 机制 运行期开销
AOP 动态代理(S07-B03) 有(一次间接调用)
MapStruct 编译期生成实现类 无(就是普通方法调用)
BeanUtils(反射) 反射拷贝 有(明显)

2. AOP 的边界(复习 + 补充)

能切 切不到
Spring 管理的 Bean 的 public 方法 同类内部自调用(S07-B03)
接口/类代理 private/final/static
方法级 字段访问

"为什么 AOP 常被误用":把业务逻辑塞进切面 → 代码更难追踪。判据:这段逻辑"业务"吗? 是 → 不该在切面里。


3. MapStruct:编译期生成(E-S27-014)

@Mapper
interface UserMapper {
    UserVO toVO(User user);        // 编译期生成实现,字段名自动匹配
}
优点 注意
无反射开销 字段名不一致要显式 @Mapping
编译期检查 嵌套对象要配 @Mapper(uses=...)
可调试(生成源码可见) 复杂转换逻辑仍要手写

判据:"这段转换在热路径上吗?" 在 → MapStruct;一次性/低频 → 反射工具也行,但要接受开销。


4. 三者选型速查

场景 选
日志/事务/权限 AOP
实体 ↔ DTO 转换(多、重复) MapStruct
字段少、临时用 手写或反射
热路径、高性能 MapStruct 或手写

5. 五个误区

误区 真相
"AOP 能切所有方法" 自调用/private 切不到
"切面里写业务更清晰" 追踪困难
"MapStruct 没开销" 无反射开销,但仍有方法调用
"反射拷贝够用了" 热路径上明显慢
"字段名不同也能自动映射" 需显式 @Mapping

6. 自检

  1. 三者机制差异?
  2. AOP 切不到哪些?
  3. MapStruct 的收益与注意点?
  4. 热路径该选什么?
  5. 为什么"业务逻辑不该在切面里"?

7. 下一篇

S27-J05 · 架构演进:从模块化到 SOA

转换讲完,下一篇讲"什么时候该拆服务"。


本篇属于系列《S27 · 杂项归档与工具实测》。旧文来源:A-381/374 + 相关卡;扩展点 E-S27-014。

S27-J04 · AOP 与对象转换:代理、拦截、MapStruct
https://www.clxhxhhr.top/posts/5622/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。