-
Notifications
You must be signed in to change notification settings - Fork 208
服务发现 装饰增强
xiaojinzi123 edited this page Mar 14, 2021
·
1 revision
Component 的服务发现是采用 Api + Impl 的形式的. Impl 可以在任意一个模块去实现. 然后 Api 需要暴露给使用者.
然后使用类似的代码去获取使用:
// Api 接口
interface BillingService {
// 是否是会员
fun isVip(): Boolean
// 去订阅
fun toSubscribe()
// ..... 还有很多方法
}
// 获取订阅的 Service
val billingService = ServiceManager.get(BillingService.class)
// 获取是否是会员
val isVip = billingService.isVip()
这时候我们的诉求就是以下几点:
- 不侵入原有的 Impl 实现的代码. (我们订阅的实现比较重要, 如果改错了就是 p0 级别的事故)
- 使用方便. 可插拔的设计
- 支持 N 次增强.
我们需要对 BillingService 增强的话, 我们可以实现下面的方式(Kotlin):
// 你只需要增强你想增强的方法, 其余的还是调用原有的方法
@ServiceDecoratorAnno(BillingService::class)
class DevelopBillingServiceImpl(val targetService: BillingService): BillingService by targetService {
// 增强的方法
fun isVip() {
if (DevelopHelper.isSetVip()) {
retrun DevelopHelper.isDevelopVip()
} else {
retrun target.isVip()
}
}
}
上面这样子就实现了对实现中的某一个方法进行了增强. 多亏了 Kotlin 的 by 委托模式的出现, 可以少写很多模板代码. 如果你使用 Java, 你必须实现接口中的所有方法, 然后挨个调用 targetService 中的方法! 用 Java 写也不是不可以, 只不过会麻烦很多哦
上述的代码, 如果跑起来, 上面的增强是一定会存在的. 但是有时候我想的是 Debug 的时候生效, 但是 Release 是不生效的.
所以增强的类支持一个注解:@ConditionalAnno
怎么用呢?
// 你只需要增强你想增强的方法, 其余的还是调用原有的方法
@ServiceDecoratorAnno(BillingService::class)
// 使用条件, 这个会在生成代码的时候. 影响这个增强的类是否会生效.
@ConditionalAnno(conditions = [DevelopCondition::class])
class DevelopBillingServiceImpl(val targetService: BillingService): BillingService by targetService {
// 增强的方法
fun isVip() {
if (DevelopHelper.isSetVip()) {
retrun DevelopHelper.isDevelopVip()
} else {
retrun target.isVip()
}
}
}
class DevelopCondition : Condition {
override fun matches(): Boolean {
return BuildConfig.isDebug
}
}