Service:插件中的长期服务对象¶
Service 用来封装可复用的插件逻辑。平台会按需创建服务实例,并保证对应作用域内只有一个实例。
服务类型¶
| 类型 | 作用域 | 适合场景 |
|---|---|---|
| Application Service | 整个 IDE 进程 | 全局配置、跨项目缓存、全局客户端 |
| Project Service | 单个项目 | 项目级状态、项目级索引协调、项目配置 |
| Module Service | 单个模块 | 很少使用;大型项目中容易增加内存压力 |
一般优先使用 Application Service 或 Project Service。
Light Service¶
如果服务不需要被其他插件覆盖,也不作为公开 API,优先使用 @Service 注解。
import com.intellij.openapi.components.Service
@Service(Service.Level.PROJECT)
class MyProjectService {
fun doWork() {
// project-level logic
}
}
获取服务:
val service = project.getService(MyProjectService::class.java)
Application 级服务:
@Service
class MyAppService {
fun doWork() {
// application-level logic
}
}
val service = com.intellij.openapi.application.ApplicationManager
.getApplication()
.getService(MyAppService::class.java)
构造函数规则¶
服务构造函数应尽量轻量:
- 不要在构造函数里做耗时初始化。
- 不要在构造函数里主动获取一堆其他服务。
- Project Service 可以接收
Project。 - Kotlin 协程场景可以接收平台提供的
CoroutineScope。
示例:
@Service(Service.Level.PROJECT)
class MyProjectService(
private val project: com.intellij.openapi.project.Project
) {
fun projectName(): String = project.name
}
非 Light Service 注册¶
如果服务需要接口、测试实现、Headless 实现或希望暴露给其他插件,可以在 plugin.xml 中声明:
<extensions defaultExtensionNs="com.intellij">
<projectService
serviceInterface="com.example.MyProjectService"
serviceImplementation="com.example.MyProjectServiceImpl"/>
</extensions>
生命周期与清理¶
需要释放资源时实现 Disposable:
class MyService : com.intellij.openapi.Disposable {
override fun dispose() {
// close resources
}
}
不要自己猜测 IDE 关闭时机。把资源挂到平台生命周期上,让平台负责调用清理逻辑。