亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringCloud Gateway自動裝配實現(xiàn)流程詳解

 更新時間:2022年10月21日 10:59:30   作者:Polarisy丶  
Spring Cloud Gateway旨在為微服務(wù)架構(gòu)提供一種簡單有效的、統(tǒng)一的 API 路由管理方式。Spring Cloud Gateway 作為 Spring Cloud 生態(tài)系中的網(wǎng)關(guān),它不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全、監(jiān)控/埋點和限流等

啟動依賴

找到gateway的依賴,spring-cloud-starter-gateway

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

點進去之后找到它的依賴

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter</artifactId>
      <version>3.1.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gateway-server</artifactId>
      <version>3.1.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
      <version>2.6.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-loadbalancer</artifactId>
      <version>3.1.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
  </dependencies>

從名稱上可以判斷spring-cloud-gateway-server是gateway的核心依賴,找到依賴包,看到如下結(jié)構(gòu)

spring.factories是一些自動裝配的類,如下可以看到

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayResilience4JCircuitBreakerAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayNoLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration,\
org.springframework.cloud.gateway.discovery.GatewayDiscoveryClientAutoConfiguration,\
org.springframework.cloud.gateway.config.SimpleUrlHandlerMappingGlobalCorsAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayReactiveOAuth2AutoConfiguration

org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.gateway.config.GatewayEnvironmentPostProcessor

# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.cloud.gateway.support.MvcFoundOnClasspathFailureAnalyzer

其中比較重要的是GatewayAutoConfiguration,負責很多bean的初始化,類聲明如下:

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class,
		GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {			

@AutoConfigureBefore@AutoConfigureAfter分別是在之前和之后加載

其中HttpHandlerAutoConfigurationWebFluxAutoConfiguration算是比較重要的裝配類

WebFluxAutoConfiguration

先看WebFluxAutoConfiguration,類聲明如下:

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnClass(WebFluxConfigurer.class)
@ConditionalOnMissingBean({ WebFluxConfigurationSupport.class })
@AutoConfigureAfter({ ReactiveWebServerFactoryAutoConfiguration.class, CodecsAutoConfiguration.class,
		ReactiveMultipartAutoConfiguration.class, ValidationAutoConfiguration.class,
		WebSessionIdResolverAutoConfiguration.class })
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebFluxAutoConfiguration {

其中部分代碼如下:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ WebProperties.class, WebFluxProperties.class })
@Import({ EnableWebFluxConfiguration.class })
@Order(0)
public static class WebFluxConfig implements WebFluxConfigurer {

可以看到通過WebFluxAutoConfiguration 通過 WebFluxConfig 導入了 EnableWebFluxConfiguration

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ WebProperties.class, ServerProperties.class })
public static class EnableWebFluxConfiguration extends DelegatingWebFluxConfiguration {

EnableWebFluxConfiguration繼承于DelegatingWebFluxConfiguration

@Configuration(proxyBeanMethods = false)
public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport {

DelegatingWebFluxConfiguration又繼承于WebFluxConfigurationSupport

在WebFluxConfigurationSupport中可以看到很熟悉的東西

@Bean
public DispatcherHandler webHandler() {
    //BeanName為webHandler
	return new DispatcherHandler();
}

有點聯(lián)想到DispatcherSerlvet,類似前端控制器

public class DispatcherHandler implements WebHandler, PreFlightRequestHandler, ApplicationContextAware {<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->

可以看到DispatcherHandler實現(xiàn)了WebHandler接口并實現(xiàn)了其中的handle方法

public interface WebHandler {
	/**
	 * Handle the web server exchange.
	 * @param exchange the current server exchange
	 * @return {@code Mono<Void>} to indicate when request handling is complete
	 */
	Mono<Void> handle(ServerWebExchange exchange);
}

可以猜到handle應(yīng)該就是核心的處理方法,此時又有疑問,該方法什么時候被調(diào)用,被誰調(diào)用的

官方文檔上提到WebHandler 上面還有一個關(guān)鍵的 API HttpHandler

For server request processing there are two levels of support.

HttpHandler: Basic contract for HTTP request handling with non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty, Undertow, Tomcat, Jetty, and any Servlet 3.1+ container.

WebHandler API: Slightly higher level, general-purpose web API for request handling, on top of which concrete programming models such as annotated controllers and functional endpoints are built.

從上面的英文可以看到 HttpHandler 是比 WebHandler 更加底層的一個 API,也就是說很可能是由 HttpHandler 來調(diào)用 WebHandler (請求由下往上),那DispatcherHandler作為 WebHandler 的一個實現(xiàn),也很有可能會被HttpHandler的具體實現(xiàn)所持有。

通過HttpHandler的實現(xiàn)類不難找到HttpWebHandlerAdapter 就是我們要找的,并且持有一個WebHandher 對象,當然也可以通過斷點調(diào)試找到。

public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHandler {<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->

HttpWebHandlerAdapter繼承于WebHandlerDecorator

public class WebHandlerDecorator implements WebHandler {
	private final WebHandler delegate;
	/**
	 * Return the wrapped delegate.
	 */
	public WebHandler getDelegate() {
		return this.delegate;
	}

可以看到WebHandlerDecorator持有WebHandler對象

總之,我們找到了調(diào)用 DispatcherHandher 的地方了,那下一步我們要找 HttpWebHandlerAdapter 是在哪里被裝配的,并且webHandler 是是什么時候被注入的,注入的 webHandler 是否就是 DispatcherHandler?

HttpHandlerAutoConfiguration

前面說過的另外一個裝配類HttpHandlerAutoConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DispatcherHandler.class, HttpHandler.class })
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnMissingBean(HttpHandler.class)
@AutoConfigureAfter({ WebFluxAutoConfiguration.class })
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class HttpHandlerAutoConfiguration {
	@Configuration(proxyBeanMethods = false)
	public static class AnnotationConfig {
		private final ApplicationContext applicationContext;
		public AnnotationConfig(ApplicationContext applicationContext) {
			this.applicationContext = applicationContext;
		}
		@Bean
		public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {
			HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
			WebFluxProperties properties = propsProvider.getIfAvailable();
			if (properties != null && StringUtils.hasText(properties.getBasePath())) {
				Map<String, HttpHandler> handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler);
				return new ContextPathCompositeHandler(handlersMap);
			}
			return httpHandler;
		}
	}
}

可以看到這里注入了一個HttpHandler對象,難道就是HttpWebHandlerAdapter ,繼續(xù)往下看

首先調(diào)用了WebHttpHandlerBuilder.applicationContext(this.applicationContext)方法,點進去看

	public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) {
		WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder(
				context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context);
	    ......
		return builder;		

可以看到通過context上下文對象通過beanName獲取bean來作為參數(shù)初始化WebHttpHandlerBuilder對象

/** Well-known name for the target WebHandler in the bean factory. */
public static final String WEB_HANDLER_BEAN_NAME = "webHandler";

而這個beanName正式前面說過的DispatcherHandler對象

	private WebHttpHandlerBuilder(WebHandler webHandler, @Nullable ApplicationContext applicationContext) {
		Assert.notNull(webHandler, "WebHandler must not be null");
		this.webHandler = webHandler;
		this.applicationContext = applicationContext;
	}

WebHttpHandlerBuilder中的webHandler屬性賦值為DispatcherHandler對象

接著進入build()方法,整體可以看到返回的HttpHandler對象就是HttpWebHandlerAdapter

	public HttpHandler build() {
		WebHandler decorated = new FilteringWebHandler(this.webHandler, this.filters);
		decorated = new ExceptionHandlingWebHandler(decorated,  this.exceptionHandlers);
		HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated);
		if (this.sessionManager != null) {
			adapted.setSessionManager(this.sessionManager);
		}
		if (this.codecConfigurer != null) {
			adapted.setCodecConfigurer(this.codecConfigurer);
		}
		if (this.localeContextResolver != null) {
			adapted.setLocaleContextResolver(this.localeContextResolver);
		}
		if (this.forwardedHeaderTransformer != null) {
			adapted.setForwardedHeaderTransformer(this.forwardedHeaderTransformer);
		}
		if (this.applicationContext != null) {
			adapted.setApplicationContext(this.applicationContext);
		}
		adapted.afterPropertiesSet();
		return (this.httpHandlerDecorator != null ? this.httpHandlerDecorator.apply(adapted) : adapted);
	}

首先看第一行

//這里的webHandler就是DispatcherHandler對象
WebHandler decorated = new FilteringWebHandler(this.webHandler, this.filters);
	public FilteringWebHandler(WebHandler handler, List<WebFilter> filters) {
		super(handler);
		this.chain = new DefaultWebFilterChain(handler, filters);
	}

調(diào)用父類的構(gòu)造方法

private final WebHandler delegate;	
public WebHandlerDecorator(WebHandler delegate) {
		Assert.notNull(delegate, "'delegate' must not be null");
		this.delegate = delegate;
	}

此時將delegate賦值為DispatcherHandler對象

接著第二行

//此時入?yún)⒅械膁ecorated是FilteringWebHandler對象
decorated = new ExceptionHandlingWebHandler(decorated,  this.exceptionHandlers);
	public ExceptionHandlingWebHandler(WebHandler delegate, List<WebExceptionHandler> handlers) {
		super(delegate);
		List<WebExceptionHandler> handlersToUse = new ArrayList<>();
		handlersToUse.add(new CheckpointInsertingHandler());
		handlersToUse.addAll(handlers);
		this.exceptionHandlers = Collections.unmodifiableList(handlersToUse);
	}

再次調(diào)用父類的構(gòu)造方法將此對象的父類中delegate屬性賦值為FilteringWebHandler對象

接著第三行

HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated);
	public HttpWebHandlerAdapter(WebHandler delegate) {
		super(delegate);
	}

一樣的道理將父類中delegate屬性賦值為ExceptionHandlingWebHandler對象

總結(jié)一下

HttpWebHandlerAdapter中delegate保存的是ExceptionHandlingWebHandler

ExceptionHandlingWebHandler中的delegate保存的是FilteringWebHandler

FilteringWebHandler中的delegate保存的是DispatcherHandler

到此這篇關(guān)于SpringCloud Gateway自動裝配實現(xiàn)流程詳解的文章就介紹到這了,更多相關(guān)SpringCloud Gateway內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 靜態(tài)鏈表實現(xiàn)示例詳解

    java 靜態(tài)鏈表實現(xiàn)示例詳解

    這篇文章主要為大家介紹了java 靜態(tài)鏈表實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Java Socket實現(xiàn)單線程通信的方法示例

    Java Socket實現(xiàn)單線程通信的方法示例

    這篇文章主要介紹了Java Socket實現(xiàn)單線程通信的方法,結(jié)合具體實例形式分析了java socket單線程通信的原理與客戶端、服務(wù)器端相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • Java8 Collectors求和功能的自定義擴展操作

    Java8 Collectors求和功能的自定義擴展操作

    這篇文章主要介紹了Java8 Collectors求和功能的自定義擴展操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Android讀取本地或網(wǎng)絡(luò)圖片并轉(zhuǎn)換為Bitmap

    Android讀取本地或網(wǎng)絡(luò)圖片并轉(zhuǎn)換為Bitmap

    這篇文章主要為大家詳細介紹了Android讀取本地或網(wǎng)絡(luò)圖片,并轉(zhuǎn)換為Bitmap,感興趣的小伙伴們可以參考一下
    2016-08-08
  • 淺談一下Spring中的createBean

    淺談一下Spring中的createBean

    createBean是創(chuàng)建Bean的主要方法, 該方法位于:AbstractBeanFactory的doGetBean方法中的createBean調(diào)用。本文就來淺談一下Spring中的createBean?,感興趣的可以了解一下
    2022-07-07
  • 在Spring Boot中處理文件上傳功能實現(xiàn)

    在Spring Boot中處理文件上傳功能實現(xiàn)

    這篇文章主要介紹了如何在Spring Boot中處理文件上傳,通過配置文件上傳屬性、創(chuàng)建控制器來處理上傳的文件,并通過異常處理器來管理錯誤情況,可以快速實現(xiàn)文件上傳功能,需要的朋友可以參考下
    2024-06-06
  • SpringBoot+WebSocket實現(xiàn)IM及時通訊的代碼示例

    SpringBoot+WebSocket實現(xiàn)IM及時通訊的代碼示例

    項目中碰到需要及時通訊的場景,使用springboot集成websocket,即可實現(xiàn)簡單的及時通訊,本文介紹springboot如何集成websocket、IM及時通訊需要哪些模塊、開發(fā)和部署過程中遇到的問題、以及實現(xiàn)小型IM及時通訊的代碼,需要的朋友可以參考下
    2023-10-10
  • 如何利用Spring?Boot?監(jiān)控?SQL?運行情況

    如何利用Spring?Boot?監(jiān)控?SQL?運行情況

    這篇文章主要介紹了如何利用Spring?Boot監(jiān)控SQL運行情況,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • GitLab在IDEA中回滾主分支問題

    GitLab在IDEA中回滾主分支問題

    這是工作中遇到的問題,記錄下來,也方便自己后面查看操作步驟,也方便各位遇到這個問題,不至于卡太久,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Spring事件監(jiān)聽詳解

    Spring事件監(jiān)聽詳解

    這篇文章主要介紹了Spring事件監(jiān)聽詳解,文中有非常詳細的圖文解說及代碼示例,對正在學習java Spring的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05

最新評論