欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringCloud Gateway自動(dòng)裝配實(shí)現(xiàn)流程詳解

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

啟動(dòng)依賴

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

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

點(diǎn)進(jìn)去之后找到它的依賴

  <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是一些自動(dòng)裝配的類,如下可以看到

# 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,負(fù)責(zé)很多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 {

可以看到通過(guò)WebFluxAutoConfiguration 通過(guò) WebFluxConfig 導(dǎo)入了 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();
}

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

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

可以看到DispatcherHandler實(shí)現(xiàn)了WebHandler接口并實(shí)現(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)該就是核心的處理方法,此時(shí)又有疑問(wèn),該方法什么時(shí)候被調(diào)用,被誰(shuí)調(diào)用的

官方文檔上提到WebHandler 上面還有一個(gè)關(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 更加底層的一個(gè) API,也就是說(shuō)很可能是由 HttpHandler 來(lái)調(diào)用 WebHandler (請(qǐng)求由下往上),那DispatcherHandler作為 WebHandler 的一個(gè)實(shí)現(xiàn),也很有可能會(huì)被HttpHandler的具體實(shí)現(xiàn)所持有。

通過(guò)HttpHandler的實(shí)現(xiàn)類不難找到HttpWebHandlerAdapter 就是我們要找的,并且持有一個(gè)WebHandher 對(duì)象,當(dāng)然也可以通過(guò)斷點(diǎn)調(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對(duì)象

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

HttpHandlerAutoConfiguration

前面說(shuō)過(guò)的另外一個(gè)裝配類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;
		}
	}
}

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

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

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

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

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

而這個(gè)beanName正式前面說(shuō)過(guò)的DispatcherHandler對(duì)象

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

WebHttpHandlerBuilder中的webHandler屬性賦值為DispatcherHandler對(duì)象

接著進(jìn)入build()方法,整體可以看到返回的HttpHandler對(duì)象就是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對(duì)象
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;
	}

此時(shí)將delegate賦值為DispatcherHandler對(duì)象

接著第二行

//此時(shí)入?yún)⒅械膁ecorated是FilteringWebHandler對(duì)象
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)造方法將此對(duì)象的父類中delegate屬性賦值為FilteringWebHandler對(duì)象

接著第三行

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

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

總結(jié)一下

HttpWebHandlerAdapter中delegate保存的是ExceptionHandlingWebHandler

ExceptionHandlingWebHandler中的delegate保存的是FilteringWebHandler

FilteringWebHandler中的delegate保存的是DispatcherHandler

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

相關(guān)文章

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

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

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

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

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

    Java8 Collectors求和功能的自定義擴(kuò)展操作

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

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

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

    淺談一下Spring中的createBean

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

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

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

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

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

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

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

    GitLab在IDEA中回滾主分支問(wèn)題

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

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

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

最新評(píng)論