包含Spring Data Rest到mappings endpoint中

21 2月

Spring Boot提供了一套方便使用的endpoint,暴露了常用的一些应用信息,比如路由情况,堆栈情况等等,灵活的使用不仅可以加快调试,也可以方便运维。

RequestMappingEndpoint类提供了地址为mappings的endpoint,提供了是当前的路由情况,什么样的路径解析到什么样的执行器中。大概的输出如下

mapping-endpoint-sample

当然,任何你自己定义的Controller等等,都会被自动包含到这个mappings中。但是如果你使用Spring Data Rest,你就会发现它的相关信息并没有被包含到这个里面。

Mappings Endpoint原理

要解决这个问题,就需要先来看看RequestMappingEndpoint是如何工作的。

首先它并没有缓存,这意味着每次访问的时候它都会调用invoke方法来获取信息

而Spring中的路由的映射大致讲只有两种,一种是UrlHandlerMapping,一种是MethodMapping。我们最常用的Controller配合RequestMapping的属于后者。

而处理这两种情况都是从applicationContext中获取所有实例,然后提取信息。唯一的不同是两种映射的对应信息保持方式不同而已。

那么以这种逻辑来看,Spring Data Rest的映射也必然在这其中才对,为什么没有显示出来?

RepositoryRestHandlerMapping和其初始化

Spring Data Rest的映射是由RepositoryRestHandlerMapping处理的AbstractHandlerMethodMapping。

也就是说在RequestMappingEndpoint从上下文中获取所有MethodMapping的时候就应该获取到它。

那么来看看它的初始化过程,具体代码在RepositoryRestMvcConfiguration中

可以看到对上下文而言,暴露的只有DelegatingHandlerMapping本身,并没有暴露RepositoryRestHandlerMapping,而DelegatingHandlerMapping实现的是HandlerMapping。

也就是说只要暴露RepositoryRestHandlerMapping,那么mappings endpoint就能工作了。

遗憾的是RepositoryRestMvcConfiguration是data-rest-webmvc的一部分,没有修改,所以实在需要这些信息只有自己去获取并暴露出来。

暴露Spring Data Rest路由信息

自定义一个endpoint,对于invoke方法

当然,这段代码只是一个例子,并没有做任何安全检查和空判断。

最后效果如下:

data-rest-included-in-mappings

参考资料

https://github.com/spring-projects/spring-boot/issues/4541

发表评论

电子邮件地址不会被公开。