ServiceEvent
ServiceEvent
继承关系
类描述
An event relating to a registered service. This is called in a {@link
org.bukkit.plugin.ServicesManager}
代表与
Service
有关的事件。本事件一般在org.bukkit.plugin.ServicesManager
类内被触发。
译注:该事件未实现
getHandlers()
和getHandlerList()
方法,无法直接监听。ServicesManager
类内不会触发该事件,而是触发该事件的下级类,即ServiceRegisterEvent
和ServiceUnregisterEvent
。所谓
Service
,其实是模仿JDK
中的ServiceLoader
设计的。它是用来管理接口与实现类的一套工具。可以参考 https://javaguide.cn/java/basis/spi.html#spi-%E5%92%8C-api-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB 了解详情。以下用
Bukkit
插件开发领域的例子作解释:Service
是一套接口。没有实现类。ServiceProvider
是具体的实现类。对于一般的API
来说,API
和其Implementation
是由同一个团队开发的。一套API
对应一个实现。但是Service
不同。一个Service
可以由很多个ServiceProvider
实现,然后通过ServicesManager
进行管理。比如著名插件Vault
提供了一些与货币操作有关的接口,但是它没有实现类。一些经济插件,比如CMI Injector
等,作为ServiceProvider
实现了这些接口。这些插件把自己的实现类告诉ServicesManager
。于是插件开发者调用Vault
提供的方法时,实际上是告诉ServicesManager
自己需要使用Vault
这个Service
,由ServicesManager
查找服务器上有哪个经济插件实现了Vault
的接口,然后将ServiceProvider
返回给开发者,开发者不需要关心ServiceProvider
具体是什么,只知道ServicesManager
提供的类是实现了Service
所规定的接口的,然后使用即可。这样做的好处是,插件开发者不需要依赖某个具体的经济插件,只要依赖一个
Vault
即可进行开发。如果没有ServicesManager
,开发者可能需要依赖具体的经济插件,这些插件各自有不同的API
,要由调用者去一个一个作适配。假如某个服务器使用的经济插件恰好未受支持,那就无法使用。而有了ServicesManager
,开发者就只需要依赖Vault
,服务器上只要安装了实现Vault
接口的经济插件就可以使用了。在
Bukkit API
中,Service
不需要注册。所谓注册操作,实际上是ServiceProvider
进行注册,将自身所实现的Service
告诉ServicesManager
。ServicesManager
便在该Service
所对应的实现类列表中添加一项。用户使用时,直接查找某个Service
对应哪些ServiceProvider
,如果没有就返回null
。Service
不需要注册自身。倘若是Service
注册自身,那Service
的开发者怎么知道有多少人为自己的这套接口提供了实现呢?难道开发一款经济插件还需要报备给Vault
插件的开发团队?当然
JDK
中的Service
系统更复杂一些,用户依赖于Service
的同时,其实对具体的ServiceProvider
也有一定的依赖。比如ScriptEngine
是一套Service
,它的实现既包括Nashorn
等ECMAscript
语言的引擎,也有如jruby
等实现,支持非ECMAscript
语言。如果用户只管查找ScriptEngine
的实现类,然后提供一个后缀为.js
的文件要求执行,而不管自己获取到的引擎具体是用来加载哪种语言的,那显然很荒谬。不过在Bukkit API
内,Service
系统有所简化,无需关心ServiceProvider
了。
方法列表
getProvider
方法声明: public RegisteredServiceProvider<?> getProvider()
方法签名: ()Lorg/bukkit/plugin/RegisteredServiceProvider;
译注:无文档。该方法用于获取涉事
ServiceProvider
。
Last updated