错误情景
- 环境:
- Spring: 2.7.18
- 操作:
- 顶层方法分析所选数据源
- 切换数据源
- 调用对应查询
- AOP代理失效导致多数据源切换失败
1 |
|
错误诱因
Spring AOP 原理:@DS 依赖 AOP 代理,而 this.xxx() 直接调用自身方法,不会经过代理对象。
JDK 代理与 CGLIB 代理的区别:默认情况下,@Transactional 和 @DS 这种 AOP 机制都是基于代理的,需要从代理对象调用方法才能生效。
解决方案
方式 1:使用 @Lazy 注解注入自身(推荐)
1
2
3@Lazy
@Autowired
private DataBaseMetaService self;这样 self.byXXX() 实际是从代理对象调用,从而触发 AOP,确保 @DS 切换数据源生效。
方式 2:通过 AopContext 获取代理对象
1
2DataBaseMetaService proxy = (DataBaseMetaService) AopContext.currentProxy();
proxy.byMaster(tableName);需要开启 exposeProxy = true,在 application.yml 配置:
1
2
3
4spring:
aop:
proxy-target-class: true
expose-proxy: true但这种方式代码侵入性较强,不如方式 1 优雅。
方式 3:将 byXXX() 方法抽取到另一个 @Service。这样 @DS 标注的方法始终在被代理对象上执行,避免 this 调用导致 AOP 失效。
结尾
我这里选择第一种解决方案,注入自身。
1 |
|