本文主要研究一下springcloud的GatewayControllerEndpoint

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {//......@Beanpublic AfterRoutePredicateFactory afterRoutePredicateFactory() {return new AfterRoutePredicateFactory();}@Beanpublic BeforeRoutePredicateFactory beforeRoutePredicateFactory() {return new BeforeRoutePredicateFactory();}@Beanpublic BetweenRoutePredicateFactory betweenRoutePredicateFactory() {return new BetweenRoutePredicateFactory();}@Beanpublic CookieRoutePredicateFactory cookieRoutePredicateFactory() {return new CookieRoutePredicateFactory();}@Beanpublic HeaderRoutePredicateFactory headerRoutePredicateFactory() {return new HeaderRoutePredicateFactory();}@Beanpublic HostRoutePredicateFactory hostRoutePredicateFactory() {return new HostRoutePredicateFactory();}@Beanpublic MethodRoutePredicateFactory methodRoutePredicateFactory() {return new MethodRoutePredicateFactory();}@Beanpublic PathRoutePredicateFactory pathRoutePredicateFactory() {return new PathRoutePredicateFactory();}@Beanpublic QueryRoutePredicateFactory queryRoutePredicateFactory() {return new QueryRoutePredicateFactory();}@Beanpublic ReadBodyPredicateFactory readBodyPredicateFactory(ServerCodecConfigurer codecConfigurer) {return new ReadBodyPredicateFactory(codecConfigurer);}//......@Configuration@ConditionalOnClass(Health.class)protected static class GatewayActuatorConfiguration {@Bean@ConditionalOnEnabledEndpointpublic GatewayControllerEndpoint gatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,RouteLocator routeLocator) {return new GatewayControllerEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);}}
}
复制代码

可以看到最后有一个GatewayActuatorConfiguration,在有actuator类库的前提下则会配置,配置的是GatewayControllerEndpoint

GatewayControllerEndpoint

spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java

@RestControllerEndpoint(id = "gateway")
public class GatewayControllerEndpoint implements ApplicationEventPublisherAware {private static final Log log = LogFactory.getLog(GatewayControllerEndpoint.class);private RouteDefinitionLocator routeDefinitionLocator;private List<GlobalFilter> globalFilters;private List<GatewayFilterFactory> GatewayFilters;private RouteDefinitionWriter routeDefinitionWriter;private RouteLocator routeLocator;private ApplicationEventPublisher publisher;public GatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,RouteLocator routeLocator) {this.routeDefinitionLocator = routeDefinitionLocator;this.globalFilters = globalFilters;this.GatewayFilters = GatewayFilters;this.routeDefinitionWriter = routeDefinitionWriter;this.routeLocator = routeLocator;}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher publisher) {this.publisher = publisher;}// TODO: Add uncommited or new but not active routes endpoint@PostMapping("/refresh")public Mono<Void> refresh() {this.publisher.publishEvent(new RefreshRoutesEvent(this));return Mono.empty();}@GetMapping("/globalfilters")public Mono<HashMap<String, Object>> globalfilters() {return getNamesToOrders(this.globalFilters);}@GetMapping("/routefilters")public Mono<HashMap<String, Object>> routefilers() {return getNamesToOrders(this.GatewayFilters);}private <T> Mono<HashMap<String, Object>> getNamesToOrders(List<T> list) {return Flux.fromIterable(list).reduce(new HashMap<>(), this::putItem);}private HashMap<String, Object> putItem(HashMap<String, Object> map, Object o) {Integer order = null;if (o instanceof Ordered) {order = ((Ordered)o).getOrder();}//filters.put(o.getClass().getName(), order);map.put(o.toString(), order);return map;}// TODO: Flush out routes without a definition@GetMapping("/routes")public Mono<List<Map<String, Object>>> routes() {Mono<Map<String, RouteDefinition>> routeDefs = this.routeDefinitionLocator.getRouteDefinitions().collectMap(RouteDefinition::getId);Mono<List<Route>> routes = this.routeLocator.getRoutes().collectList();return Mono.zip(routeDefs, routes).map(tuple -> {Map<String, RouteDefinition> defs = tuple.getT1();List<Route> routeList = tuple.getT2();List<Map<String, Object>> allRoutes = new ArrayList<>();routeList.forEach(route -> {HashMap<String, Object> r = new HashMap<>();r.put("route_id", route.getId());r.put("order", route.getOrder());if (defs.containsKey(route.getId())) {r.put("route_definition", defs.get(route.getId()));} else {HashMap<String, Object> obj = new HashMap<>();obj.put("predicate", route.getPredicate().toString());if (!route.getFilters().isEmpty()) {ArrayList<String> filters = new ArrayList<>();for (GatewayFilter filter : route.getFilters()) {filters.add(filter.toString());}obj.put("filters", filters);}if (!obj.isEmpty()) {r.put("route_object", obj);}}allRoutes.add(r);});return allRoutes;});}/*
http POST :8080/admin/gateway/routes/apiaddreqhead uri=http://httpbin.org:80 predicates:='["Host=**.apiaddrequestheader.org", "Path=/headers"]' filters:='["AddRequestHeader=X-Request-ApiFoo, ApiBar"]'
*/@PostMapping("/routes/{id}")@SuppressWarnings("unchecked")public Mono<ResponseEntity<Void>> save(@PathVariable String id, @RequestBody Mono<RouteDefinition> route) {return this.routeDefinitionWriter.save(route.map(r ->  {r.setId(id);log.debug("Saving route: " + route);return r;})).then(Mono.defer(() ->Mono.just(ResponseEntity.created(URI.create("/routes/"+id)).build())));}@DeleteMapping("/routes/{id}")public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {return this.routeDefinitionWriter.delete(Mono.just(id)).then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build()))).onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));}@GetMapping("/routes/{id}")public Mono<ResponseEntity<RouteDefinition>> route(@PathVariable String id) {//TODO: missing RouteLocatorreturn this.routeDefinitionLocator.getRouteDefinitions().filter(route -> route.getId().equals(id)).singleOrEmpty().map(route -> ResponseEntity.ok(route)).switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));}@GetMapping("/routes/{id}/combinedfilters")public Mono<HashMap<String, Object>> combinedfilters(@PathVariable String id) {//TODO: missing global filtersreturn this.routeLocator.getRoutes().filter(route -> route.getId().equals(id)).reduce(new HashMap<>(), this::putItem);}
}
复制代码

可以看到提供了如下几个rest api

  • POST /refresh
  • GET /globalfilters
  • GET /routefilters
  • GET /routes
  • POST /routes/{id}
  • GET /routes/{id}
  • GET /routes/{id}/combinedfilters

实例

/actuator/gateway/routes

[{"route_id": "CompositeDiscoveryClient_DISCOVERY-SERVICE","route_definition": {"id": "CompositeDiscoveryClient_DISCOVERY-SERVICE","predicates": [{"name": "Path","args": {"pattern": "/DISCOVERY-SERVICE/**"}}],"filters": [{"name": "RewritePath","args": {"regexp": "/DISCOVERY-SERVICE/(?<remaining>.*)","replacement": "/${remaining}"}}],"uri": "lb://DISCOVERY-SERVICE","order": 0},"order": 0},{"route_id": "CompositeDiscoveryClient_GATEWAY-SERVICE","route_definition": {"id": "CompositeDiscoveryClient_GATEWAY-SERVICE","predicates": [{"name": "Path","args": {"pattern": "/GATEWAY-SERVICE/**"}}],"filters": [{"name": "RewritePath","args": {"regexp": "/GATEWAY-SERVICE/(?<remaining>.*)","replacement": "/${remaining}"}}],"uri": "lb://GATEWAY-SERVICE","order": 0},"order": 0}
]
复制代码

/actuator/gateway/globalfilters

{"org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@f425231": 10100,"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@5cbd94b2": -1,"org.springframework.cloud.gateway.filter.NettyRoutingFilter@506aabf6": 2147483647,"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@756aadfc": 10000,"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@705a8dbc": 2147483647,"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@6824b913": 2147483637,"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@40729f01": 2147483646
}
复制代码

/actuator/gateway/routefilters

{"[RedirectToGatewayFilterFactory@32f96bba configClass = RedirectToGatewayFilterFactory.Config]": null,"[StripPrefixGatewayFilterFactory@4a481728 configClass = StripPrefixGatewayFilterFactory.Config]": null,"[RemoveResponseHeaderGatewayFilterFactory@67e25252 configClass = AbstractGatewayFilterFactory.NameConfig]": null,"[RequestHeaderToRequestUriGatewayFilterFactory@4ace284d configClass = AbstractGatewayFilterFactory.NameConfig]": null,"[ModifyRequestBodyGatewayFilterFactory@b3e86d5 configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,"[RemoveRequestHeaderGatewayFilterFactory@611640f0 configClass = AbstractGatewayFilterFactory.NameConfig]": null,"[SetStatusGatewayFilterFactory@3fd05b3e configClass = SetStatusGatewayFilterFactory.Config]": null,"[PreserveHostHeaderGatewayFilterFactory@4d0e54e0 configClass = Object]": null,"[SetResponseHeaderGatewayFilterFactory@1682c08c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,"[SecureHeadersGatewayFilterFactory@76ececd configClass = Object]": null,"[SaveSessionGatewayFilterFactory@4eb9f2af configClass = Object]": null,"[AddResponseHeaderGatewayFilterFactory@75b6dd5b configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,"[PrefixPathGatewayFilterFactory@e111c7c configClass = PrefixPathGatewayFilterFactory.Config]": null,"[SetRequestHeaderGatewayFilterFactory@7affc159 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,"[RewritePathGatewayFilterFactory@58f4b31a configClass = RewritePathGatewayFilterFactory.Config]": null,"[SetPathGatewayFilterFactory@72eb6200 configClass = SetPathGatewayFilterFactory.Config]": null,"[RetryGatewayFilterFactory@21a9a705 configClass = RetryGatewayFilterFactory.Retry]": null,"[AddRequestHeaderGatewayFilterFactory@1f1cddf3 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,"[ModifyResponseBodyGatewayFilterFactory@72b43104 configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,"[AddRequestParameterGatewayFilterFactory@228bda54 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null
}
复制代码

/actuator/gateway/routes/CompositeDiscoveryClient_DISCOVERY-SERVICE

{"id": "CompositeDiscoveryClient_DISCOVERY-SERVICE","predicates": [{"name": "Path","args": {"pattern": "/DISCOVERY-SERVICE/**"}}],"filters": [{"name": "RewritePath","args": {"regexp": "/DISCOVERY-SERVICE/(?<remaining>.*)","replacement": "/${remaining}"}}],"uri": "lb://DISCOVERY-SERVICE","order": 0
}
复制代码

/actuator/gateway/routes/CompositeDiscoveryClient_DISCOVERY-SERVICE/combinedfilters

{"Route{id='CompositeDiscoveryClient_DISCOVERY-SERVICE', uri=lb://DISCOVERY-SERVICE, order=0, predicate=org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$769/1774209584@7d9639ad, gatewayFilters=[OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda$771/1052389952@528c8627, order=1}]}": 0
}
复制代码

小结

springcloud gateway提供了一个gateway actuator,该endpiont提供了关于filter及routes的信息查询以及指定route信息更新的rest api,这给web界面提供管理配置功能提供了极大的便利。

doc

  • Part XV. Spring Cloud Gateway 115. Actuator API

聊聊springcloud的GatewayControllerEndpoint相关推荐

  1. 聊聊 SpringCloud 中的父子容器

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 来源公号:吉姆餐厅ak 概述 在引入 SpringCloud 的项目中会多次创建 Spring 容 ...

  2. 这 10 道 Spring Boot 常见面试题你需要了解下

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号:Java团长 1.什么是Spring Boot? 多年来,随着新功能的增加,sp ...

  3. 再有人问你Netty是什么,就把这篇文章发给他

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号:Hollis 本文基于Netty4.1展开介绍相关理论模型,使用场景,基本组件. ...

  4. 一次生产 CPU 100% 排查优化实践

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号 crossoverJie 前言 到了年底果然都不太平,最近又收到了运维报警:表示 ...

  5. JAVA面试--电商业内大厂

    技术面试轮次论 首先其实各个公司的面试流程几乎是大同小异,分为多轮面试,许多初入职场的同学可能觉得多论面试无非就是多个人一起把把关,或者公司的hr要求面试流程使然,其实这些理解都太片面了,为什么需要技 ...

  6. QQ好友分组模拟小程序

    QQ好友分组:一个好友组里有多个好友,一个好友只能选择一个组,这样好友组和好友之间就是一个一对多的关系.在此程序中封装一个好友类即Buddy类,一个组类即Group类.在Buddy类有有关好友的最基本 ...

  7. SpringCloud 之 Zuul 网关搭建及配置

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:Anakki blog.csdn.net/qq_29 ...

  8. 跟大家聊聊我们为什么要学习源码?学习源码对我们有用吗?(源码感悟)

    来自:源码笔记 1 前言 由于现在微服务很流行,越来越多企业采用了SpringCloud微服务架构,而SpringBoot则是快速构建微服务项目的利器.于是笔者以此为切入点,将SpringBoot作为 ...

  9. properties 配置回车_非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!...

    本文同步Java知音社区,专注于Java 作者:kosamino http://www.cnblogs.com/jing99/p/11696192.html Zuul是spring cloud中的微服 ...

  10. 从架构演进的角度聊聊Spring Cloud都做了些什么?

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...

最新文章

  1. Nat Commun:宏基因组学提示曙古菌门的代谢和进化(中大李文均组)
  2. VB 输入超出文件尾(错误62)(转)
  3. Charles拦截与篡改
  4. 我国是世界最大石油进口国,但是大家知道从哪些国家进口吗?
  5. (JAVA)超大小数运算
  6. JDK源码解析之 java.lang.Long
  7. navigation右边按钮点击事件
  8. SQL:postgresql中判断字段是否为某个值的方法IN操作符
  9. 国密SM2算法陷入安全危机? 假!SM2仍然安全
  10. 竖版1:2500万标准中国地图
  11. 台式/笔记本无线网卡_异常问题
  12. php的解析别名,浅谈laravel aliases别名的原理
  13. oracle学习app,Oracle学习相关
  14. 淘宝详情页分发推荐算法总结:用户即时兴趣强化
  15. docker安装ElasticSearch8.1.0错误curl: (52) Empty reply from server的处理方法
  16. python用类名直接调用方法_一文读全 Python 的面向对象编程方法
  17. 皮尔森(Pearson correlation coefficient)相关系数—统计学三大相关系数之一
  18. matlab 计算两个函数的卷积
  19. 安装时提示错误1402的解决办法
  20. 快速登陆github的方法之一

热门文章

  1. Vue.js 2.0 和 React、Augular等其他框架的全方位对比
  2. Sass 基本特性-基础 笔记
  3. 使用Pixel Bender Toolkit制作特效——给过滤器增加参数(Part 3)
  4. UML---StarUML破解与使用
  5. 利用gsoap工具,通过wsdl文件生成webservice的C++工程文件
  6. window10 无法访问 Toshiba e-studio355 扫描打印一体机的机器扫描文件夹
  7. ArcGIS模型操作
  8. javascript -- 事件代理
  9. 第二次冲刺站立会议10
  10. .NET应用程序与数据库交互的若干问题