如何使用spring-boot和pf4j将应用程序的端点与外部插件混合



我已经创建了一个spring-boot应用程序(2.6.4(,我想使用p4fj集成一些插件。我以前在非spring引导应用程序中使用过p4fj,但现在它有了p4fj-spring来帮助实现这一过程。

这个想法不仅是集成插件方法,而且检查如何集成一些端点。为此,我遵循官方教程。这里的重点是,对于包括插件端点(基于@RestController,而不是反应式端点(,建议:

private void registerMvcEndpoints(PluginManager pm) {
pm.getExtensions(PluginInterface.class).stream()
.flatMap(g -> g.mvcControllers().stream())
.forEach(r -> ((ConfigurableBeanFactory) beanFactory)
.registerSingleton(r.getClass().getName(), r));
applicationContext
.getBeansOfType(RequestMappingHandlerMapping.class)
.forEach((k, v) -> v.afterPropertiesSet());
}

该方法的第一部分是从插件中获得所需的类并将其注册为bean,这很好,以便稍后在第二部分注册为端点。为此,它使用了RequestMappingHandlerMapping.class。如果我们遵循教程中的示例,那么对于没有自己的端点的应用程序来说,它可以很好地工作,并且它只是从外部插件注册端点。

我面临的问题是,当我试图混合一个已经有一些端点(由@RestController定义(的应用程序时,我想从一个或多个插件中添加一些额外的端点。在运行前面的代码时,我收到一个错误,告诉我应用程序的端点不能注册为已经存在。

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: Ambiguous handler methods mapped for '/health-check': {public void my.package.webservice.Info.healthCheck(javax.servlet.http.HttpServletRequest), public void my.package.webservice.Info.healthCheck(javax.servlet.http.HttpServletRequest)}

似乎,当我们试图从插件中包括所有端点时,它也再次包括所有应用程序端点,因此它面临着任何端点的URL和方法的唯一性限制。我已经调试过了,事实上RequestMappingHandlerMapping似乎已经从spring boot注册的应用程序端点(以及插件(获得了信息。

我试着创建一个自定义的RequestMappingHandlerMapping,但这只会增加更多的重复。我也尝试过从前面显示的registerMvcEndpoints方法中过滤应用程序端点(即通过包或url(,但我没有成功,因为我们不是一个接一个地注册,而是一起在afterPropertiesSet()中注册。

那么,问题是……我如何才能避免标准spring-boot初始化程序已经注册的端点的注册?或者,还有其他方法可以注册插件端点吗?

如果您想在Spring Boot上使用pf4j,sbp是一个很好的开始;(

最新更新