SpringCloud Gateway 로 딩 단언 predicates 와 필터 filter 의 소스 코드 분석
13044 단어 SpringCloudGateway단언필터
4.567915.다른 블 로 거들 은 더 이상 말 하지 않 겠 습 니 다.여러분 은 홈 페이지 에 많이 가 보 세 요.공식 적 인 것 만 이 가장 정확 합 니 다.주제 로 돌아 갑 니 다.우리 의 필터 와 단언 이 어떻게 불 러 왔 는 지,그리고 어떻게 요 구 를 걸 러 냈 는 지 확인 하 세 요.
SpringBoot 자동 로 딩 에 익숙 하 다 면 코드 의 소스 코드 를 봐 야 한 다 는 것 을 알 아야 합 니 다.META-INF 에 있 는 spring.factories 를 찾 아야 합 니 다.구체 적 으로 왜 블 로 거들 은 더 이상 말 하지 않 습 니까?인터넷 에 도 자동 으로 로 딩 된 소스 코드 분석 이 많 습 니 다.오늘 은 Gateway 를 설명 하 겠 습 니 다.모든 프로젝트 의 스 리 스트로크 도끼:의존,주석 쓰기,설정 을 하 겠 습 니 다.
의존:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
설명:시작 클래스 에@EnableDiscoveryClient 를 추가 해 야 합 니 다.시작 서비스 발견설정:
spring:
cloud:
gateway:
routes:
- id: after-route #id
uri: lb://product-center
predicates:
- After=2030-12-16T15:53:22.999+08:00[Asia/Shanghai]
filters:
- PrefixPath=/product-api
여러분 이 이 설정 을 보 았 을 때,왜 우 리 는 After 단언 과 PrefixPath 필 터 를 쓰 면 gateway 가 자동 으로 인식 되 는 지,그러면 우 리 는 모든 자체 테이프 의 속성 을 볼 수 있 는 곳 이 있 습 니까?물론 있 습 니 다.그리고 이 편 은 왜 gateway 가 자동 으로 인식 되 는 지 설명 하고 사용자 정의 속성 을 추가 해 야 합 니 다.원본 코드 분석 첫 번 째 단 계 를 시작 하여 자동 으로 불 러 오 는 클래스 를 찾 습 니 다.이곳 을 보 았 을 때 첫 번 째 단 계 는 성공 적 이 었 습 니 다.나머지 는 org.spring from work.cloud.gateway.config.Gateway AutoConfiguration 이라는 관건 적 인 종 류 를 찾 았 습 니 다.우 리 는 주로 안의 두 가지 종 류 를 보 았 습 니 다.
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
List<GatewayFilterFactory> GatewayFilters,
List<RoutePredicateFactory> predicates,
RouteDefinitionLocator routeDefinitionLocator) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
}
@Bean
@Primary
//TODO: property to disable composite?
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
이 두 가지 유형 설정 은 모두 가 잘 알 고 있 을 것 입 니 다.여러분 이 새로운 지식 을 손 에 넣 었 을 때 빠 른 입문 글 을 찾 아 볼 것 입 니 다.블 로 거들 은 공식 적 인 quick start 를 직접 찾 아 보 는 습관 이 있 습 니 다.여러분 은 이런 빠 른 시작 항목 을 볼 수 있 습 니 다https://spring.io/projects/spring-cloud-gateway그래서 블 로 거들 은 RouteLocator 라 는 설정 을 직접 찾 았 습 니 다.아니 나 다 를 까 우 리 는 단언 과 필터 의 주입 을 찾 았 습 니 다.실제 적 인 방법 으로 체 내 에 매개 변수 로 들 어 갔 지만 spring 에 의 해 해석 되 었 습 니 다.공장 에 가서 직접 받 았 습 니 다.구체 적 으로 어떻게 가 져 갑 니까?우리 다시 한번 봅 시다.
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
.....
for (Method candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {
String[] paramNames = null;
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
//
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
.....
return bw;
}
모든 매개 변 수 는 해석 이 필요 하지만 여 기 를 보면 괜 찮 은 것 같 지 않 습 니 다.계속 내 려 가면 보 입 니 다.
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
....
// ,
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
....
try {
// --resolveAutowiredArgument
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
args.resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
// ,
...
return args;
}
분석 을 시 작 했 을 때 보 았 습 니 다.단언 과 필터 목록 을 모두 추가 해 야 합 니 다.그러면 spring 은 어떻게 불 러 옵 니까?방법 에 따라 체 내 에 들 어 오 는 유형 에 따라 단언 과 필터 공장 인 터 페 이 스 를 실현 하 는 모든 종 류 를 찾 고 인 스 턴 스 를 얻 습 니 다.우 리 는 이 공장 들 의 실현 류 를 자세히 살 펴 보면 우리 가 사용 하 는 속성 을 찾 을 수 있 습 니 다.예 를 들 어 우리 사례 의 PrefixPath 필터 와 Path 단언 등 입 니 다.
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// ,beanNamesForTypeIncludingAncestors , bean ,
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
...
// ,
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
.....
return result;
}
이제 우 리 는 시스템 설정 의 단언 과 필터 가 어떻게 불 러 오 는 지 알 게 되 었 습 니 다.그러면 우 리 는 또 하나의 문제 가 있 습 니 다.만약 내 가 하 나 를 사용자 정의 한다 면 어떻게 시스템 에 의 해 인식 되 는 지 알 게 되 었 습 니 다.그리고 설정 은 어떻게 하나 요?우리 가 이전에 소스 코드 를 보 았 을 때 그 는 spring 에 의 해 공장 실현 류 를 찾 아 불 러 왔 다 는 것 을 알 수 있 습 니 다.그러면 우 리 는 공장 인 터 페 이 스 를 실현 하고@Component 주 해 를 사용 하여 spring 을 불 러 오 면 되 지 않 습 니까?하지만 시스템 사용자 정의 속성 단언 이나 필터 에 공장 이름 의 접미사 가 있 는 것 을 발견 할 수 있 습 니 다.왜 일 까요?사용자 정의 클래스 가 gateway 에 불 러 오고 유효 합 니까?사실은 영향 을 줄 수 있 는데,왜 영향 을 줍 니까?우 리 는 소스 코드 를 보 는 것 이 좋 겠 다.우리 가 이전에 클래스 로 딩 을 다 보지 못 했 기 때문에 우 리 는 처음에 두 개의@bean 의 자동 로 딩 을 찾 았 습 니 다.그러면 이 두 가지 사례 화 할 때 어떤 일 을 했 는 지 우 리 는 아직 자세히 보지 못 했 습 니 다.
public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,
List<RoutePredicateFactory> predicates,
List<GatewayFilterFactory> gatewayFilterFactories,
GatewayProperties gatewayProperties) {
this.routeDefinitionLocator = routeDefinitionLocator;
initFactories(predicates);
gatewayFilterFactories.forEach(factory -> this.gatewayFilterFactories.put(factory.name(), factory));
this.gatewayProperties = gatewayProperties;
}
initFactory(predicates):이 코드 는 주로 공장 실현 류 를 분석 하 는 것 입 니 다.그리고 지도 에 넣 고,gateway FilterFactories.foreach(factory->this.gateway FilterFactories.put(factory.name(),factory):단언 코드 와 거의 같 습 니 다.다른 논리 가 없 기 때문에 방법 에 봉인 되 지 않 고 자바 8 의 흐름 특성 을 직접 사용 하여 옮 겨 다 니 는 과정 을 썼 습 니 다.여러분 은 코드 가 factory.name()이라는 것 을 주의해 야 합 니 다.여기 서 방법 을 사 용 했 습 니 다.
default String name() {
return NameUtils.normalizeRoutePredicateName(getClass());
}
주로 현재 클래스 의 공장 이름 을 포함 하 는 부분 을 제거 한 다음 에 남 은 문자열 을 key 값 으로 사용 하기 때문에 우 리 는 공장 이름 을 사용 하여 펜던트 를 할 수도 있 고 사용 하지 않 아 도 된다.그러나 나머지 문 자 는 당신 이 설정 한 키 워드 를 써 야 한다.그러나 블 로 거들 은 기본적으로 시스템 자체 속성 과 마찬가지 로 공장 인터페이스의 이름 으로 접 두 사 를 만 들 었 다.자,오늘 은 이렇게 많은 것 을 설명 하 겠 습 니 다.다음 에는 gateway 가 요청 을 받 은 후에 어떻게 한 걸음 한 걸음 걸 러 냈 는 지,언제 단언 검 사 를 했 는 지 설명 하 겠 습 니 다.한 번 에 이렇게 많은 것 을 말 하지 않 고 소화 하면 된다.
스프링 클 라 우 드 게 이 트 웨 이 로 딩 단언 predicates 와 필터 filter 의 소스 코드 분석 에 관 한 글 은 여기까지 소개 되 었 습 니 다.더 많은 스프링 클 라 우 드 게 이 트 웨 이 단언 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 을 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
SpringCloud OAuth2 + JWT 인증 인증(一) 인증 서버Spring Cloud oAuth2(1) 라이센스 서버 구축 및 액세스 Spring Cloud oAuth2(2) 리소스 서버 구축 및 테스트 SpringCloud OAuth2 + JWT 인증 인증(一) 인증 서버 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.