# 插件结构
一个Sermant的插件中可包含以下模块:
插件主模块(plugin)
,该模块主要用于声明字节码增强逻辑及插件服务接口定义插件服务模块(service)
,该模块用于为插件包提供插件服务接口实现
开始之前,需要明确约定,为避免类冲突问题,在插件主模块(plugin)
中,开发者只能使用Java原生API和sermant-agentcore模块中的API,不能依赖或使用任何除byte-buddy
以外的第三方依赖。如果应业务要求,需要使用其他第三方依赖的话,只能在插件主模块(plugin)
中定义功能接口,并在插件服务模块(service)
中编写接口实现,在开发中遵循上述约定,才可以更好的利用到Sermant提供的类隔离能力。
# sermant-agentcore模块
sermant-agentcore模块是Sermant Agent的核心模块,其中提供了字节码增强能力、类隔离能力、插件化能力、服务治理的基础服务等核心能力的封装。
# 插件主模块
插件主模块是插件的主要实现,开发者需要在该模块中声明该插件的增强逻辑。增强逻辑开发可参考字节码增强章节。为避免类冲突问题,插件主模块中不可引入第三方依赖。
# 插件服务模块
插件服务模块较插件主模块相比:
# 插件服务
插件服务主要分为两部分:
服务接口定义在插件主模块中用于描述该服务提供的能力,在定义插件的插件服务时,需要继承插件服务基础接口com.huaweicloud.sermant.core.PluginService (opens new window),该接口提供start()
方法会在Sermant启动时被调用,stop()
方法会在JVM停止时被调用。
服务接口实现在插件服务模块中,在插件主模块中可以通过SPI机制加载并使用插件服务的接口实现。
# 开发示例
本开发示例基于创建首个插件文档中创建的工程。
注:该开发示例下描述的插件服务接口及其实现已在模板工程中存在,可直接使用,无需重复创建,本示例详细描述其创建过程可以使开发者更易于理解开发过程。
在开发插件服务时,首先需要在插件主模块中定义插件服务的接口,这是使用插件服务时的索引,在工程中template\template-plugin
下创建com.huaweicloud.sermant.template.EchoService
接口,并在其中定义echo
接口方法:
public interface EchoService extends PluginService {
void echo(String string);
}
接口定义完成后,需要在插件服务模块提供上述接口的实现,来执行实际的逻辑,在工程中template\template-service
中创建com.huaweicloud.sermant.template.EchoServiceImpl
类,其需要实现com.huaweicloud.sermant.template.EchoService
接口,并实现接口中定义的echo
接口方法:
public class EchoServiceImpl implements EchoService {
@Override
public void echo(String string) {
// 回应别人的问候
string = string.replaceAll("[\\pP+~$`^=|<>~`$^+=|<>¥×]", "");
System.out.println("ECHO: " + string + " to you!");
}
}
开发插件服务的最后,不要忘记添加插件服务的SPI配置,在工程中template\template-service
下的资源目录resources
中添加META-INF/services
目录,并在其中创建名为com.huaweicloud.sermant.core.plugin.service.PluginService
的SPI文件,并向其中添加插件服务实现类的类名:
com.huaweicloud.sermant.template.EchoServiceImpl
接下来,找到工程中template\template-plugin
下的com.huaweicloud.sermant.template.TemplateDeclarer
类,在针对main
方法的拦截器的before
方法中使用已经开发完成的插件服务,通过com.huaweicloud.sermant.core.plugin.service.PluginServiceManager (opens new window)插件服务管理器获取插件服务并使用:
注:
com.huaweicloud.sermant.core.plugin.service.PluginServiceManager::getPluginService(Class clazz)
可通过插件服务接口基于Java SPI机制获取插件服务实现的实例。
public ExecuteContext before(ExecuteContext context) throws Exception {
System.out.println("Good morning!");
PluginServiceManager.getPluginService(EchoService.class).echo("Good morning!");
return context;
}
开发完成后,可参照创建首个插件时的打包构建流程,在工程根目录下执行 mvn package,执行完成后在根目录执行 cd agent/
,并在其中携带Sermant运行测试应用,执行如下命令 java -javaagent:sermant-agent.jar -jar Application.jar
$ java -javaagent:sermant-agent.jar -jar Application.jar
[INFO] Loading core library...
[INFO] Building argument map...
[INFO] Loading sermant agent...
[INFO] Load sermant done.
Good morning!
ECHO: Good morning to you!
可以看到,招呼得到了回应,我们创建的插件服务已经生效了,如需要开发新的插件服务,按照上述开发示例执行即可。