SpringCloud Gateway 경로 설정 포 지 셔 닝 원리 분석
11038 단어 SpringCloudGateway경로의 원리
이 절 은 시스템 의 서술 어 와 설정 의 경로 정보 가 어떻게 초기 화 되 는 지 알 고 있 습 니 다.모든 술어 공장 의 Config 대상 은 어떻게 설정 되 어 있 습 니까?
모든 술어 공장 의 Config 속성 값 이 어떻게 설정 되 어 있 습 니까?
SpringCloud Gateway 의 모든 서술 어 공장 은 다음 과 같다.
명명 규칙:XxRoute PredicateFactory.모든 서술 어 공장 은 다음 과 같은 상속 관계 이다.
public class MethodRoutePredicateFactory extends AbstractRoutePredicateFactory<MethodRoutePredicateFactory.Config>
//
public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config>
// ...
공장 상속AbstractRoute Predicate Factory 의 범 형 은 모두 내부 클래스 의 Config 입 니 다.이것 은 어떻게 값 이 설정 되 어 있 습 니까?
6.1 게 이 트 웨 이 자동 설정
다음 클래스 에 모든 Predicate 와 Filter 를 설정 합 니 다.
public class GatewayAutoConfiguration {
@Bean
@ConditionalOnEnabledPredicate
public PathRoutePredicateFactory pathRoutePredicateFactory() {
return new PathRoutePredicateFactory();
}
@Bean
@ConditionalOnEnabledPredicate
public QueryRoutePredicateFactory queryRoutePredicateFactory() {
return new QueryRoutePredicateFactory();
}
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties, List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> predicates, RouteDefinitionLocator routeDefinitionLocator, ConfigurationService configurationService) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,
gatewayFilters, properties, configurationService);
}
@Bean
@Primary
@ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
}
여 기 는 층 층 이 의뢰 를 해서 최종 검색 루트 를 찾 아서 위치 추적 을 맡 기 겠 습 니 다.RouteDefinitionRouteLocator。CachingRouteLocator 는 캐 시 역할 을 하 며 설정 한 모든 경로 정 보 를 저장 합 니 다.
메모:이 경로 정 보 는 용기 가 시 작 된 후에 초기 화 됩 니 다.
public class CachingRouteLocator {
private final RouteLocator delegate;
private final Flux<Route> routes;
private final Map<String, List> cache = new ConcurrentHashMap<>();
private ApplicationEventPublisher applicationEventPublisher;
public CachingRouteLocator(RouteLocator delegate) {
this.delegate = delegate;
routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class) .onCacheMissResume(this::fetch);
}
private Flux<Route> fetch() {
return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);
}
}
CachingRouteLocator 를 예화 하면 모든 설정 의 Route 정 보 를 찾기 시작 합 니 다.최종 의뢰 는RouteDefinitionRouteLocator
RouteDefinitionRouteLocator 구조 함수 의 initFactory 방법 은 공장 의 Xxx Route PredicateFactory 를 비 추 는 데 사 용 됩 니 다.
private void initFactories(List<RoutePredicateFactory> predicates) {
predicates.forEach(factory -> {
String key = factory.name();
if (this.predicates.containsKey(key)) {
this.logger.warn("A RoutePredicateFactory named " + key + " already exists, class: " + this.predicates.get(key) + ". It will be overwritten.");
}
this.predicates.put(key, factory);
});
}
방법 에서 모든 술어 공장 에 대응 하 는 이름 을 분석 하고 predicates 집합 에 캐 시 합 니 다.factory.name()방법 은 술어 이름 을 해석 합 니 다.
default String name() {
return NameUtils.normalizeRoutePredicateName(getClass());
}
CachingRouteLocator 는 캐 시 경로 지정 기 입 니 다.우선 선택 한 RouteLocator(@Primary)입 니 다.Route Definition Route Locator 가 합병 되 었 습 니 다.
6.2 경로 생 성 대상 Route 및 Config 설정
getRoutes---》convertToRoute---》combinePredicates---》lookup。
위의 자동 설정 에 따 르 면 서비스 가 시 작 될 때 모든 경로 정 보 를 초기 화 하 는 것 을 알 수 있 습 니 다.
경로 정보 가 져 오기
public Flux<Route> getRoutes() {
Flux<Route> routes = this.routeDefinitionLocator.getRouteDefinitions() .map(this::convertToRoute);
routes = routes.onErrorContinue((error, obj) -> {
return routes.map(route -> {
return route;
});
}
병합 술어
private AsyncPredicate<ServerWebExchange> combinePredicates(
RouteDefinition routeDefinition) {
// other code
for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
predicate = predicate.and(found);
}
return predicate;
}
lookup 에 들 어가 기
private AsyncPredicate<ServerWebExchange> lookup(RouteDefinition route, PredicateDefinition predicate) {
RoutePredicateFactory<Object> factory = this.predicates.get(predicate.getName());
if (factory == null) {
throw new IllegalArgumentException("Unable to find RoutePredicateFactory with name " + predicate.getName());
}
// (yml ) name,args Config
Object config = this.configurationService.with(factory)
.name(predicate.getName())
.properties(predicate.getArgs())
.eventFunction((bound, properties) -> new PredicateArgsEvent(
RouteDefinitionRouteLocator.this, route.getId(), properties))
.bind();
// (XxxRoutePredicateFactory apply RoutePredicate Predicate)
return factory.applyAsync(config);
}
lookup 방법 에서 찾 습 니 다.즉,여기 서 대응 하 는 서술 어 Config 와 Route Definition(Predicate)에서 정의 하 는 대응 하 는 속성 과 연 결 됩 니 다.factory.apply Async 에 들 어 가 는 방법
@FunctionalInterface
public interface RoutePredicateFactory<C> extends ShortcutConfigurable, Configurable<C> {
default AsyncPredicate<ServerWebExchange> applyAsync(C config) {
return toAsyncPredicate(apply(config)); // 6.2-1 apply XxxRoutePredicateFactory
}
}
// apply(config), Path , PathRoutePredicateFactory apply
public Predicate<ServerWebExchange> apply(Config config) {
// other code
return new GatewayPredicate() {
public boolean test() {
// todo
}
}
}
//
public static AsyncPredicate<ServerWebExchange> toAsyncPredicate(Predicate<? super ServerWebExchange> predicate) {
Assert.notNull(predicate, "predicate must not be null");
// from DefaultAsyncPredicate
return AsyncPredicate.from(predicate);
}
static AsyncPredicate<ServerWebExchange> from( Predicate<? super ServerWebExchange> predicate) {
return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
}
그림 6.2-1마지막 으로 combinePredicates 방법 에서 현재 경로 에 설 정 된 모든 서술 어 를 and 작업 으로 되 돌려 줍 니 다.최종 적 으로 convertToRoute 방법 으로 돌아 가 현재 경로 에 설 치 된 서술 어,필 터 를 통합 포장 하여 Route(경로 대상)로 되 돌려 줍 니 다.
public class Route implements Ordered {
private final String id;
private final URI uri;
private final int order;
private final AsyncPredicate<ServerWebExchange> predicate;
private final List<GatewayFilter> gatewayFilters;
private final Map<String, Object> metadata;
}
이 Route 대상 들 은 위 에 저장 되 어 있 습 니 다.CachingRoute Locator.routes 중 입 니 다.
6.3 포 지 셔 닝 경로
위의 설정 에 따라 RouteLocator 와 같은 종 류 는 경 로 를 찾 습 니 다(구체 적 으로 어떤 경 로 를 사용 하 는 지 찾 습 니 다).요청 이 오 면 어떤 경로 인지 찾 을 수 있 습 니 다.
RouteLocator 에서 방법 을 정 의 했 습 니 다.
public interface RouteLocator {
Flux<Route> getRoutes();
}
이 getRoutes 방법 을 누가 호출 했 는 지 확인 합 니 다.이거 보니까.
Route Predicate Handler Mapping 은 Spring MVC 의 Handler Mapping 을 떠 올 렸 습 니까?이름 을 통 해 알 수 있 듯 이 이 Handler Mapping 은 우리 의 경로 서술 어 에 맞 는 누가 경 로 를 처리 하 는 지 알 수 있 습 니 다.
이제 앞으로 돌아 가서 말씀 드 리 겠 습 니 다.
Request MappingHanlder Mapping 대상 은 루트 주 소 를 요청 할 때 이 클래스 의 lookup 방법 을 실행 하여 루트 를 찾 습 니 다
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
// this.routeLocator CachingRouteLocator
return this.routeLocator.getRoutes()
.concatMap(route -> Mono.just(route).filterWhen(r -> {
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
//
return r.getPredicate().apply(exchange);
}).doOnError(e -> logger.error(
"Error applying predicate for route: " + route.getId(),
e)).onErrorResume(e -> Mono.empty()))
.next()
.map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("Route matched: " + route.getId());
}
validateRoute(route, exchange);
return route;
});
}
r.getPredicate().apply(exchange)에 들 어가 기
public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
static AsyncPredicate<ServerWebExchange> from(Predicate<? super ServerWebExchange> predicate) {
return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
}
class DefaultAsyncPredicate<T> implements AsyncPredicate<T> {
private final Predicate<T> delegate;
public DefaultAsyncPredicate(Predicate<T> delegate) {
this.delegate = delegate;
}
@Override
public Publisher<Boolean> apply(T t) {
return Mono.just(delegate.test(t));
}
@Override
public String toString() {
return this.delegate.toString();
}
}
}
Predicate.test 방법(XxRoute Predicate Factory 의 apply 방법 으로 돌아 오 는 Gateway Predicate)을 호출 합 니 다.Gateway Predicate.test 를 호출 하여 현재 요청 한 경로 가 일치 하 는 지 판단 합 니 다.
전체 프로 세 스:
1.시스템 은 모든 Predicate(술어)와 Filter(필터)를 초기 화 합 니 다.
2.설 정 된 경로 정보(필터,술어)에 따라 경로 대상 을 되 돌려 줍 니 다.
3.요청 경로 에 따라 일치 하 는 경로 찾기
이상!!!
스프링 클 라 우 드 게 이 트 웨 이 경로 설정 포 지 셔 닝 원리 분석 에 관 한 글 은 여기까지 입 니 다.스프링 클 라 우 드 게 이 트 웨 이 원리 분석 내용 에 대해 서 는 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Spring Cloud] LoadBancer-01discoveryservice-eureka 라는 프로젝트를 생성한다 3개 항목을 추가한다. 1. DiscoveryserviceEurekaApplication.java 생성된 -application에 @EnableEu...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.