Skip to content

服务发现 装饰增强

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()

这时候我们的诉求就是以下几点:

  1. 不侵入原有的 Impl 实现的代码. (我们订阅的实现比较重要, 如果改错了就是 p0 级别的事故)
  2. 使用方便. 可插拔的设计
  3. 支持 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
  }
}
Clone this wiki locally