插件化开发的核心目标是**在不修改核心代码的情况下动态添加功能**。通过 SPI(Service Provider Interface)机制实现插件自动发现,结合 Koin 完成依赖注入,可以在运行时自由组合功能模块,各模块独立开发、独立测试。
```
┌─────────────────────────────────────────────┐
│ App │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ KoinApplication │ │
│ │ │ │
│ │ modules(pluginModule) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ pluginModule │ │
│ │ includes(userModule) │ │
│ │ includes(orderModule) │ │
│ │ includes(paymentModule) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ServiceLoader.load(BootModule) │ │
│ │ ─ META-INF/services ─ │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
```
核心思路:**Plugin 定义插件接口,ServiceLoader 实现自动发现,Koin 统一管理依赖**。
定义一个 `Plugin` 接口,所有插件必须实现该接口。`module` 属性返回一个 Koin `Module`,用于注册插件自身的依赖:
```kotlin
interface Plugin {
val module: Module
}
```
以用户模块为例,定义业务依赖并实现 `Plugin`:
```kotlin
internal val userModule = module {
single { UserRepository() }
single { UserService(get()) }
}
object UserPlugin : Plugin {
override val module: Module = userModule
}
```
多个插件完全独立开发,互不感知。
`PluginManager` 通过 Java SPI(`ServiceLoader`)在运行时加载所有 `Plugin` 实现类。KSP 处理器在编译时自动生成 `META-INF/services` 配置文件,无需手动维护:
```kotlin
object PluginManager {
val plugins: List<Plugin> by lazy {
ServiceLoader.load(Plugin::class.java).toList()
}
}
```
生成的 `META-INF/services/com.yuanjingtech.boot.app.kmp.BootModule` 文件内容类似:
```
com.yuanjingtech.boot.app.kmp.user.UserBootModule
com.yuanjingtech.boot.app.kmp.order.OrderBootModule
com.yuanjingtech.boot.app.kmp.payment.PaymentBootModule
```
将所有插件的 `Module` 合并为一个 `pluginModule`,统一注入到 Koin:
```kotlin
val pluginModule = module {
includes(PluginManager.plugins.map { it.module })
}
```
在 Compose Multiplatform 应用中,通过 `KoinApplication` 启动:
```kotlin
@Composable
fun App() {
KoinApplication(
configuration = KoinConfiguration {
modules(pluginModule)
},
content = {
Content()
}
)
}
```
整个插件框架的核心链路:
1. **定义接口**:`Plugin` 约束插件必须提供 `Module`
2. **实现插件**:各模块实现 `Plugin`,独立开发独立测试
3. **自动发现**:SweetSPI + KSP 自动生成 `META-INF/services`,`ServiceLoader` 运行时加载
4. **统一注入**:所有插件模块合并后统一注册到 Koin
这种模式实现了核心代码零修改即可扩展功能,适合模块化的大型 KMP 项目。