SpringCloudAlibaba基础分享(八)

125 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

image.png

上一期讲到了如何实现动态网关

这一期分享一下跨域问题,以及源码的简单分析

跨域问题解决代码

@Component

public class CrossOriginFilter implements GlobalFilter {

    @Override

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();

        ServerHttpResponse response = exchange.getResponse();

        HttpHeaders headers = response.getHeaders();

        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");

        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");

        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");

        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");

        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");

        return chain.filter(exchange);

    }

}

源码分析

/**
 * @author Spencer Gibb
 * @author Ziemowit Stolarczyk
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties

@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class,
		WebFluxAutoConfiguration.class })
                
//GatewayLoadBalancerClientAutoConfiguration 网关需要使用的负载均衡
//GatewayClassPathWarningAutoConfiguration 检查是否配置我们webfux依赖
@AutoConfigureAfter({ GatewayLoadBalancerClientAutoConfiguration.class,
		GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
//加载了我们Gateway需要的注入的类。
public class GatewayAutoConfiguration {
	//加载时间信息
	@Bean
	public StringToZonedDateTimeConverter stringToZonedDateTimeConverter() {
		return new StringToZonedDateTimeConverter();
	}
	//加载路由相关信息
	@Bean
	public RouteLocatorBuilder routeLocatorBuilder(
			ConfigurableApplicationContext context) {
		return new RouteLocatorBuilder(context);
	}
	//读取配置信息
	@Bean
	@ConditionalOnMissingBean
	public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(
			GatewayProperties properties) {
		return new PropertiesRouteDefinitionLocator(properties);
	}
	
	// 在内存注册的路由定义的Bean
	@Bean
	@ConditionalOnMissingBean(RouteDefinitionRepository.class)
	public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
		return new InMemoryRouteDefinitionRepository();
	}
	
	
	@Bean
	@Primary
	public RouteDefinitionLocator routeDefinitionLocator(
			List<RouteDefinitionLocator> routeDefinitionLocators) {
		return new CompositeRouteDefinitionLocator(
				Flux.fromIterable(routeDefinitionLocators));
	}
	
	//配置服务Bean,依赖 ConversionService转换服务(webFluxConversionService),与验证器
	@Bean
	public ConfigurationService gatewayConfigurationService(BeanFactory beanFactory,
			@Qualifier("webFluxConversionService") ObjectProvider<ConversionService> conversionService,
			ObjectProvider<Validator> validator) {
		return new ConfigurationService(beanFactory, conversionService, validator);
	}
	/**
	*GatewayProperties properties gateway的配置Bean
	*List<GatewayFilterFactory> gatewayFilters 所有的过滤器,所有的实现在 学习2中有说明
	*List<RoutePredicateFactory> predicates 路由断言工厂,所有的实现在 学习2中有说明
	*RouteDefinitionLocator routeDefinitionLocator :这里注入的应该是 CompositeRouteDefinitionLocator的Bean,因为它是@primary的
	* ConfigurationService configurationService 就是上面的ConfigurationService 
	*  由以上属性,生成一个 RouteDefinitionRouteLocator,
	* RouteLocator 这个接口主要是一个 Flux<Route> getRoutes(); 即获取所有的路由
	**/
	@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")
	// TODO: property to disable composite?
	public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
		return new CachingRouteLocator(
				new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
	}
	
	//路由刷新的 监听器
	@Bean
	@ConditionalOnClass(
			name = "org.springframework.cloud.client.discovery.event.HeartbeatMonitor")
	public RouteRefreshListener routeRefreshListener(
			ApplicationEventPublisher publisher) {
		return new RouteRefreshListener(publisher);
	}
	
	//FilteringWebHandler webHanlder的过滤器,依赖 GlobalFilter全局过滤器
	@Bean
	public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
		return new FilteringWebHandler(globalFilters);
	}
	
	// 解读 spring.cloud.gateway.globalcors.*的配置的Bean
	@Bean
	public GlobalCorsProperties globalCorsProperties() {
		return new GlobalCorsProperties();
	}
	

	@Bean
	public RoutePredicateHandlerMapping routePredicateHandlerMapping(
			FilteringWebHandler webHandler, RouteLocator routeLocator,
			GlobalCorsProperties globalCorsProperties, Environment environment) {
		return new RoutePredicateHandlerMapping(webHandler, routeLocator,
				globalCorsProperties, environment);
	}
	
        //gateway的配置类
	@Bean
	public GatewayProperties gatewayProperties() {
		return new GatewayProperties();
	}

	
	
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass({ HystrixObservableCommand.class, RxReactiveStreams.class })
	protected static class HystrixConfiguration {

		@Bean
		@ConditionalOnEnabledFilter
		public HystrixGatewayFilterFactory hystrixGatewayFilterFactory(
				ObjectProvider<DispatcherHandler> dispatcherHandler) {
			return new HystrixGatewayFilterFactory(dispatcherHandler);
		}

		@Bean
		@ConditionalOnMissingBean(FallbackHeadersGatewayFilterFactory.class)
		@ConditionalOnEnabledFilter
		public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() {
			return new FallbackHeadersGatewayFilterFactory();
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Health.class)
	protected static class GatewayActuatorConfiguration {

		@Bean
		@ConditionalOnProperty(name = "spring.cloud.gateway.actuator.verbose.enabled",
				matchIfMissing = true)
		@ConditionalOnAvailableEndpoint
		public GatewayControllerEndpoint gatewayControllerEndpoint(
				List<GlobalFilter> globalFilters,
				List<GatewayFilterFactory> gatewayFilters,
				List<RoutePredicateFactory> routePredicates,
				RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator,
				RouteDefinitionLocator routeDefinitionLocator) {
			return new GatewayControllerEndpoint(globalFilters, gatewayFilters,
					routePredicates, routeDefinitionWriter, routeLocator,
					routeDefinitionLocator);
		}

		@Bean
		@Conditional(OnVerboseDisabledCondition.class)
		@ConditionalOnAvailableEndpoint
		public GatewayLegacyControllerEndpoint gatewayLegacyControllerEndpoint(
				RouteDefinitionLocator routeDefinitionLocator,
				List<GlobalFilter> globalFilters,
				List<GatewayFilterFactory> gatewayFilters,
				List<RoutePredicateFactory> routePredicates,
				RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) {
			return new GatewayLegacyControllerEndpoint(routeDefinitionLocator,
					globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter,
					routeLocator);
		}

	}

	private static class OnVerboseDisabledCondition extends NoneNestedConditions {

		OnVerboseDisabledCondition() {
			super(ConfigurationPhase.REGISTER_BEAN);
		}

		@ConditionalOnProperty(name = "spring.cloud.gateway.actuator.verbose.enabled",
				matchIfMissing = true)
		static class VerboseDisabled {

		}

	}

}

总结:

1. GatewayClassPathWarningAutoConfiguration 检查是否配置我们webfux依赖。

2. GatewayAutoConfiguration加载了我们Gateway需要的注入的类。

3. GatewayLoadBalancerClientAutoConfiguration 网关需要使用的负载均衡

4. GatewayRedisAutoConfiguration  网关整合Redis整合Lua实现限流

5. GatewayDiscoveryClientAutoConfiguration 服务注册与发现功能