场景

支付服务同时依赖仓储、风控和日志,如果对象自己创建依赖,替换实现与测试会很困难;若每个方法又手写事务和审计,业务逻辑会被横切代码淹没。

原理

IoC 把对象创建和依赖装配交给容器,DI 是实现控制反转的主要方式。AOP 则在连接点应用通知,Spring 通常借助 JDK 动态代理或 CGLIB 包装 Bean,让事务、监控等逻辑围绕方法执行。

设计步骤

先用接口或明确职责拆分依赖并采用构造注入;再识别真正跨多个模块的横切关注点;定义精确切点和执行顺序;确认调用必须经过代理;最后测试正常、异常和嵌套调用,观察代理类型及事务边界。

权衡

IoC 增强替换性,却可能因 Bean 过多使依赖图复杂;AOP 减少重复,但隐藏控制流。切点过宽会误拦截,切面过多会造成顺序耦合。核心业务规则通常不应藏进切面。

实践建议

依赖保持单向,出现循环依赖应重划职责而非依赖三级缓存“救场”。切面只处理日志、权限、事务等稳定横切能力,并输出可观测信息。自调用需要拆到独立 Bean 或改为显式编排,避免通过暴露代理制造更深耦合。

落地检查

上线前还应做一次桌面演练:准备正常、边界、超时、重复与恶意输入,确认系统的返回、日志和指标彼此对应;在预发布环境模拟依赖不可用、进程重启和配置回滚,验证降级路径不会放大故障。上线时采用小流量观察,提前定义停止条件与负责人。稳定后复盘真实数据,删除没有收益的复杂度,并把新发现的约束补进测试、监控和设计记录,使方案能够随业务持续演进,而不是停留在一次性评审结论。