##yml配置
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设置路由
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 {
@Autowired
private RouteLocator routeLocator;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher publisher;
private void loadDynamicRoutes() {
routeDefinitionWriter.save(Mono.just(createRoute())).subscribe();
}
@Override
public 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;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
##publisher.publishEvent(new RefreshRoutesEvent(this));发布事件。调用CachingRouteLocator刷新缓存源码
private final Map<String, List> cache = new ConcurrentHashMap<>();
@Override
public 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方法
private Flux<Route> fetch() {
return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);
}
##fetch方法通过CompositeRouteLocator获取路由
@Override
public Flux<Route> getRoutes() {
return this.delegates.flatMapSequential(RouteLocator::getRoutes);
}
##spring gateway 请求阶段查找路由
从CachingRouteLocator缓存中查找
##AsyncPredicate.DefaultAsyncPredicate.apply 判断路径是否匹配
##匹配方法