君子贵人而贱己,先人而后己。——《礼记·访记》
服务是当您的插件调用相应ComponentManager
实例的方法时按需加载的插件组件。IntelliJ 平台确保仅加载服务的一个实例,即使它被多次调用也是如此。
服务必须具有用于服务实例化的实现类。服务也可能有一个接口类,用于获取服务实例并提供服务的 API。
需要关闭时清理的服务可以实现Disposable
并执行回调dispose()
。
服务用于封装在一组相关类上运行的逻辑,或者提供一些可以跨插件项目使用的可重用功能,并且在概念上与其他语言或框架中的服务类没有区别。
类型
IntelliJ 平台提供三种类型的服务:应用程序级服务(全局单例)、项目级服务和模块级服务。对于后两者,为其对应作用域的每个实例创建一个单独的服务实例。
构造函数
项目/模块级服务构造函数可以有一个Project
/Module
参数。要提高启动性能,请避免在构造函数中进行任何繁重的初始化。
服务
不会被覆盖的服务不需要在**plugin.xml**中注册。相反,使用注释服务类@Service
。服务实例将根据调用者在范围内创建。
限制:
- service等级必须是
final
. - 不支持依赖服务的构造函数注入。
- 如果服务是PersistentStateComponent,则必须禁用漫游 (
roamingType = RoamingType.DISABLED
)。
声明服务
Service每种类型提供不同的扩展点:
com.intellij.applicationService
- 应用层服务com.intellij.projectService
- 项目级服务com.intellij.moduleService
- 模块级服务
要公开服务 API,请为其创建单独的类serviceInterface
并将其扩展到在serviceImplementation
. 如果serviceInterface
未指定,它应该具有与 相同的值serviceImplementation
。
要为测试/无头环境提供自定义实现,请另外指定testServiceImplementation
/ headlessImplementation
。
plugin.xml
<extensions defaultExtensionNs="com.intellij">
<!-- Declare the application-level service -->
<applicationService
serviceInterface="mypackage.MyApplicationService"
serviceImplementation="mypackage.MyApplicationServiceImpl"/>
<!-- Declare the project-level service -->
<projectService
serviceInterface="mypackage.MyProjectService"
serviceImplementation="mypackage.MyProjectServiceImpl"/>
</extensions>
检索服务
不要急于获取服务实例或将它们存储在字段中,而是在将要使用它们的地方获取它们。
获取服务不需要读取操作,可以从任何线程执行。如果一个服务被多个线程请求,它将在第一个线程中初始化,其他线程将被阻塞,直到服务完全初始化。
MyApplicationService applicationService = ApplicationManager.getApplication()
.getService(MyApplicationService.class);
MyProjectService projectService = project.getService(MyProjectService.class);
getInstance()
服务实现可以使用方便的静态或方法包装这些调用getInstance(Project)
:
MyApplicationService applicationService = MyApplicationService.getInstance();
MyProjectService projectService = MyProjectService.getInstance(project);
获取服务流
项目服务样本
这个最小的示例显示了ProjectService
与另一个项目级服务AnotherService
(此处未显示)的交互。
ProjectService.java
@Service
public final class ProjectService {
private final Project myProject;
public ProjectService(Project project) {
myProject = project;
}
public void someServiceMethod(String parameter) {
AnotherService anotherService = myProject.getService(AnotherService.class);
String result = anotherService.anotherServiceMethod(parameter, false);
// do some more stuff
}
}