SPI 模块是服务发现和依赖注入框架,基于 Java SPI (Service Provider Interface) 机制实现。该模块提供了一个自定义的服务加载器 WeNextServiceLoader,用于动态发现和加载服务实现类,支持模块化开发和插件化架构。
META-INF/services/ 配置文件进行服务发现class WeNextServiceLoader<S> private constructor(
private val service: Class<S>,
cl: ClassLoader?
) : Iterable<S?> {
// 加载服务
companion object {
fun <S> load(service: Class<S>, loader: ClassLoader?): WeNextServiceLoader<S>
fun <S> load(service: Class<S>): WeNextServiceLoader<S>
fun <S> getFirst(service: Class<S>): S?
}
// 重新加载服务
fun reload()
// 获取第一个服务实例
fun getFirst(): S?
// 迭代器支持
override fun iterator(): MutableIterator<S?>
}
private inner class LazyIterator(
val service: Class<S>,
val loader: ClassLoader?
) : MutableIterator<S?> {
private fun hasNextService(): Boolean
private fun nextService(): S?
override fun hasNext(): Boolean
override fun next(): S?
}
interface IHello {
fun hello()
}
// 默认实现
class AHello : IHello {
override fun hello() {
Log.d("Hello", "AHello")
}
}
// 带键的实现
class BHello : IHello {
override fun hello() {
Log.d("Hello", "BHello")
}
}
在 src/main/resources/META-INF/services/ 目录下创建配置文件:
文件名: com.example.IHello
# 默认实现
com.example.AHello
# 键值实现
com.example.BHello
// 加载单个服务
val helloService = WeNextServiceLoader.getFirst(IHello::class.java)
helloService?.hello()
// 加载所有服务实现
val serviceLoader = WeNextServiceLoader.load(IHello::class.java)
serviceLoader.forEach { service ->
service?.hello()
}
// 自定义 ClassLoader
val customLoader = MyCustomClassLoader()
val loader = WeNextServiceLoader.load(IHello::class.java, customLoader)
val serviceLoader = WeNextServiceLoader.load(IHello::class.java)
// 使用迭代器
val iterator = serviceLoader.iterator()
while (iterator.hasNext()) {
val service = iterator.next()
service?.hello()
}
// 使用 for-each
for (service in serviceLoader) {
service?.hello()
}
# 注释行,以 # 开头
com.example.service.ServiceImpl1
com.example.service.ServiceImpl2
# 另一个注释
com.example.service.ServiceImpl3
META-INF/services/{接口全限定名}private val providers = LinkedHashMap<String, S>() // 实例缓存
private var lookupIterator: LazyIterator? = null // 懒加载迭代器
META-INF/services/ 配置文件androidx.core.ktx - Android 核心扩展frame:router - 路由模块使用 SPI 进行服务发现implementation "com.wenext.android:frame-spi:6.0.0"
META-INF/services/ 目录下