spring cloud gateway源码(三)Filter的加载

在SpringCloud Gateway网关中,必不可少的就是filter了,网关中的filter是分两层走的,先走一层是bean的filter,再走一层普通的filter。具体什么意思,下面我们一起来看下。

一、带bean的filter。

刚开始初始化的时候,会加载HttpHandlerAutoConfiguration类中的bean,HttpHandler,如下:

		@Bean
		public HttpHandler httpHandler() {
			return WebHttpHandlerBuilder.applicationContext(this.applicationContext)
					.build();
		}
	public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) {

		WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder(
				context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context);

		// Autowire lists for @Bean + @Order

		SortedBeanContainer container = new SortedBeanContainer();
		context.getAutowireCapableBeanFactory().autowireBean(container);

在上面代码的最后一行,去获取了了SortedBeanContainer类型的bean,而sortedBeanContainer依赖了如下两种类型的bean:

		@Autowired(required = false)
		public void setFilters(List<WebFilter> filters) {
			this.filters = filters;
		}

		@Autowired(required = false)
		public void setExceptionHandlers(List<WebExceptionHandler> exceptionHandlers) {
			this.exceptionHandlers = exceptionHandlers;
		}

而在依赖的bean类型中,一个Bean类型的filter为:WebFilterChainProxy,bean类型的WebFilter和非Bean类型的WebFilter的调用就发生在这个类上,

	@Bean(SPRING_SECURITY_WEBFILTERCHAINFILTER_BEAN_NAME)
	@Order(value = WEB_FILTER_CHAIN_FILTER_ORDER)
	public WebFilterChainProxy springSecurityWebFilterChainFilter() {
		return new WebFilterChainProxy(getSecurityWebFilterChains());
	}

这个方法在类:WebFluxSecurityConfiguration中,这个类有个属性:

@Autowired(required = false)
	private List<SecurityWebFilterChain> securityWebFilterChains;

如果这个类型的bean存在的话,就会在WebFilterChainProxy的filter方法中被调用:

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
		return Flux.fromIterable(this.filters)
				.filterWhen( securityWebFilterChain -> securityWebFilterChain.matches(exchange))
				.next()
				.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
				.flatMap( securityWebFilterChain -> securityWebFilterChain.getWebFilters()
					.collectList()
				)
				.map( filters -> new FilteringWebHandler(webHandler -> chain.filter(webHandler), filters))
				.map( handler -> new DefaultWebFilterChain(handler) )
				.flatMap( securedChain -> securedChain.filter(exchange));
	}

二、不带bean的filter

就是如果我们自定义了SecurityWebFilterChain类型的bean的话,那么我们就可以使用自定义的调用链了。类似如下:

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {

        http.authorizeExchange()
                .anyExchange().authenticated()
                .and().csrf().disable()
                .httpBasic().disable()
                .formLogin().disable()
                .logout().disable()
                .requestCache().disable();
        http.addFilterAt(authenticationWebFilter(), SecurityWebFiltersOrder.FORM_LOGIN);
        //rewrite路由转发
        http.addFilterAt(rewriteWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION);
        http.addFilterAt(authorizationWebFilter(),SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }

三、调用的地方

在bean都实例化后,实例化的Bean类型的filter就放入了WebHttpHandlerBuilder的filters属性中,然后我们回到最初获取HttpHandler()方法:

		@Bean
		public HttpHandler httpHandler() {
			return WebHttpHandlerBuilder.applicationContext(this.applicationContext)
					.build();
		}

builder()方法中有这么一行方法:

decorated = new FilteringWebHandler(this.webHandler, this.filters);

可以看到将我们获取的filter类型的bean,放入到了FilteringWebHandler的属性中,而这个FilteringWebHandler中的handle()方法就是我们过滤器走的方法。

猜你喜欢

转载自blog.csdn.net/lz710117239/article/details/81158489