静态代理重构短信网关
大约 2 分钟
1. 架构变化
2. 原方案
重构的想法来自于漏扫的短信轰炸漏洞,当时分别有三个网关实现了MessageService
,如果想统一将防止轰炸的逻辑放到redis去做的话,那么如左图:
方案A是对所有调用MessageService
的地方都添加判断,但这显然太不合理了
方案B是对所有的MessageService
都添加判断,尽管只有三个,但谁也不能确定以后是否会有更多的网关出现,这样就多出了很多的冗余代码!
3. 新方案
方案C可以创建另外一个类,来封装MessageService,这样是可以达到统一管理的目的,但是因为这个类的方法要受MessageService
中方法的约束,所以单独建一个类也不太合理
于是参考"静态代理"的思路,新方案D(右图)则出现了,将原接口提升为父接口,并新建两个空的子接口,最终在MessageServiceImpl
中使用AOP实现对原方法的增强,这样既可以保证对新需求的非侵入式修改,也可以确保新的MessageServiceImpl
实现的方法完全包含了SmsService
的方法,最重要的是这样的实现方法在SpringBoot的IOC加载过程也不会互相影响。
// 只有一个实例SmsService
@Autowired
private MessageService messageService;
// SmsService被MessageServiceImpl持有
// 因为使用了条件装载,故三个实现类也只会同时存在一个实例
@Autowired
private SmsService smsService;
4. 新的进展
2024-08-21兼容V1短信网关
今天突然又让把淘汰的老版本短信网关加回来
重构果然是明智的,极大的减小了耦合性。只需要新增的老版本短信添加一个@ConditionalOn
即可,其他的不需要修改,分分钟就接入了V1的短信网关