##yml配置
java">spring:application:name: public-gateway
# cloud:
# gateway:
# routes:
# - id: mybatis-plus-test # 路由的唯一标识
# uri: http://192.168.3.188:9898 # 目标服务的地址
# predicates:
# - Path=/test/** # 匹配以 /user/ 开头的请求路径
# filters:
# - AddRequestHeader=X-Request-Example, Example # 添加一个请求头
# - AddRequestParameter=param1, value1 # 添加一个请求参数
server:port: 8180
logging:config: classpath:config/logback-spring.xml
##DynamicRoutesService动态路由
ApplicationEventPublisherAware得到publisher发布事件刷新路由缓存
ApplicationRunner设置路由
java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;@Service
public class DynamicRoutesService implements ApplicationEventPublisherAware, ApplicationRunner {@Autowiredprivate RouteLocator routeLocator;@Autowiredprivate RouteDefinitionWriter routeDefinitionWriter;private ApplicationEventPublisher publisher;private void loadDynamicRoutes() {routeDefinitionWriter.save(Mono.just(createRoute())).subscribe();}@Overridepublic void run(ApplicationArguments args) throws Exception {loadDynamicRoutes();publisher.publishEvent(new RefreshRoutesEvent(this));}public RouteDefinition createRoute() {PredicateDefinition predicateDefinition = new PredicateDefinition();List<PredicateDefinition> predicates = new ArrayList<>();predicates.add(predicateDefinition);Map<String, String> argsPredicate = new LinkedHashMap<>();argsPredicate.put("key0", "/test/**");predicateDefinition.setName("Path");predicateDefinition.setArgs(argsPredicate);FilterDefinition filterDefinition = new FilterDefinition();List<FilterDefinition> filters = new ArrayList<>();filters.add(filterDefinition);Map<String, String> argsFilter = new LinkedHashMap<>();argsFilter.put("name", "X-Request-Example");argsFilter.put("value", "Example");filterDefinition.setName("AddRequestHeader");filterDefinition.setArgs(argsFilter);RouteDefinition routeDefinition = new RouteDefinition();routeDefinition.setUri(URI.create("http://192.168.3.104:9898"));routeDefinition.setOrder(1);routeDefinition.setId("mybatis-plus-test");routeDefinition.setPredicates(predicates);routeDefinition.setFilters(filters);return routeDefinition;}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.publisher = applicationEventPublisher;}}
##publisher.publishEvent(new RefreshRoutesEvent(this));发布事件。调用CachingRouteLocator刷新缓存源码
private final Map<String, List> cache = new ConcurrentHashMap<>();
java">@Overridepublic void onApplicationEvent(RefreshRoutesEvent event) {try {fetch().collect(Collectors.toList()).subscribe(list -> Flux.fromIterable(list).materialize().collect(Collectors.toList()).subscribe(signals -> {applicationEventPublisher.publishEvent(new RefreshRoutesResultEvent(this));cache.put(CACHE_KEY, signals);}, throwable -> handleRefreshError(throwable)));}catch (Throwable e) {handleRefreshError(e);}}
##fetch方法
java">private Flux<Route> fetch() {return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);}
##fetch方法通过CompositeRouteLocator获取路由
java">@Overridepublic Flux<Route> getRoutes() {return this.delegates.flatMapSequential(RouteLocator::getRoutes);}
从CachingRouteLocator缓存中查找
##AsyncPredicate.DefaultAsyncPredicate.apply 判断路径是否匹配
##匹配方法