KRouter 现已支持 Kotlin Multiplatform SPI 机制

143 阅读1分钟

KRouter 在前几天发布的新版 1.2.1 已经支持了 Kotlin Multiplatform SPI 机制,基于 KSP 和注解。

github.com/0xZhangKe/K…

SPI 机制

首先介绍一下 SPI 到底是什么。SPI 全称 Service Provider Interface,也被称为服务发现,在 Java 中通过 ServiceLoader 来实现。实际上是指在运行时获取一个接口所有的实现类。

如果我们某种服务通过一个接口描述,并且在源码结构上无法获取到接口所有的实现类,比如实现类分散在各个模块,甚至是运行时加载的模块,那么我们就可以通过 SPI 在运行时获取到这个接口所有的实现类。

interface HtmlParser {

    fun parse(document: String): String
}

// Module A
class Html1Parser : HtmlParser {

    override fun parse(document: String): String {
        return document
    }
}

// Module B
class Html2Parser : HtmlParser {

    override fun parse(document: String): String {
        return document
    }
}

// Application
fun main() {
    val parsers = ServiceLoader.load(HtmlParser::class.java, HtmlParser::class.java.classLoader)
}

如上,这样就是一个简单的 SPI 实现。

Kotlin SPI

上述方式是通过 Java 的能力做到的,Kotlin Multiplatform 本身没有提供这样的能力,因此只能自己想办法了。

好在 KRouter 天然具备通过注解收集信息的能力,只要稍加改造即可支持。

首先在使用上,KRouter 提供了一个 @Service 注解用于表示一个实现类,然后在编译的时候 KRouter 会自动收集类信息,这样就可以在运行时获取到所有的实现了。

interface HtmlParser {

    fun parse(document: String): String
}

// Module A
@Service
class Html1Parser : HtmlParser {

    override fun parse(document: String): String {
        return document
    }
}

// Module B
@Service(HtmlParser::class)
class Html2Parser : HtmlParser {

    override fun parse(document: String): String {
        return document
    }
}

// Application
fun main() {
    val parsers = KRouter.getServices<HtmlParser>()
}

就是这么简单,关于 KRouter 更多的使用请看上一篇文章