国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

spring cloud gateway 源碼解析(1)整體流程

miqt / 896人閱讀

摘要:公司要做自己的網(wǎng)關(guān),于是先把的過(guò)了一遍,然后把源碼在看了一遍,這樣公司的需求就搞定了。包括動(dòng)態(tài)路由,多緯度限流,記錄請(qǐng)求參數(shù)及返回參數(shù)也可修改。至此,流程就走完了。

公司要做自己的網(wǎng)關(guān),于是先把github的issue過(guò)了一遍,然后把gateway源碼在看了一遍,這樣公司的需求就搞定了。包括動(dòng)態(tài)路由,多緯度限流,記錄請(qǐng)求參數(shù)及返回參數(shù)(也可修改)。先從請(qǐng)求進(jìn)入網(wǎng)關(guān)說(shuō)起吧:
請(qǐng)求先進(jìn)入HttpWebHandlerAdapter 類(lèi)里

@Override
    public Mono handle(ServerHttpRequest request, ServerHttpResponse response) {
        ServerWebExchange exchange = createExchange(request, response);
        //getDelegate()獲取的是ExceptionHandlingWebHandler,用來(lái)處理全局的異常
        return getDelegate().handle(exchange)
                .onErrorResume(ex -> handleFailure(request, response, ex))
                .then(Mono.defer(response::setComplete));
    }

    protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) {
//這里的DefaultServerWebExchange就是后面過(guò)濾器用到的ServerWebExchange,包括封裝的請(qǐng)求參數(shù),以及再執(zhí)行過(guò)濾器時(shí)往里面添加參數(shù),參數(shù)是線(xiàn)程安全的
        return new DefaultServerWebExchange(request, response, this.sessionManager,
                getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext);
    }

往下走:

前面的getDelegate().handle(exchange)進(jìn)入DefaultWebFilterChain類(lèi)里

public class DefaultWebFilterChain implements WebFilterChain {

    private final List filters;

    private final WebHandler handler;

    private final int index;

    ·······

    @Override
    public Mono filter(ServerWebExchange exchange) {
        return Mono.defer(() -> {
            if (this.index < this.filters.size()) {//先執(zhí)行完所有的 WebFilter 
                WebFilter filter = this.filters.get(this.index);
                //這里重新new DefaultWebFilterChain然后調(diào)用filter方法,也就會(huì)順序執(zhí)行所有的過(guò)濾器了
                WebFilterChain chain = new DefaultWebFilterChain(this, this.index + 1);
                return filter.filter(exchange, chain);
            }
            else {//然后才會(huì)執(zhí)行網(wǎng)關(guān)自定義的過(guò)濾器
                return this.handler.handle(exchange);
            }
        });
    }

}

往下:

this.handler.handle(exchange),進(jìn)入到DispatcherHandler類(lèi)里

public class DispatcherHandler implements WebHandler, ApplicationContextAware {
    ····
    @Nullable
    //HandlerMapping用來(lái)判斷請(qǐng)求進(jìn)來(lái)的地址應(yīng)該怎么處理,可能會(huì)匹配到spring webflux的HandlerFunction,
    或者是controller,然后才是我們?cè)诰W(wǎng)關(guān)配置的路由,都匹配不上的話(huà)就到SimpleUrlHandlerMapping來(lái)處理404            
    了,這里其實(shí)有點(diǎn)不太明白為什么作者會(huì)把網(wǎng)關(guān)路由的優(yōu)先級(jí)設(shè)置低于HandlerFunction,controller,網(wǎng)關(guān)畢竟是            
    用來(lái)轉(zhuǎn)發(fā),所以我另外加了個(gè)類(lèi)設(shè)置了最高的優(yōu)先級(jí)(修改RoutePredicateHandlerMapping中的order)
    private List handlerMappings;

    @Nullable
    private List handlerAdapters;

    @Nullable
    //處理網(wǎng)關(guān)調(diào)用第三方服務(wù)返回的結(jié)果
    private List resultHandlers;
 
     ·····
    public DispatcherHandler(ApplicationContext applicationContext) {
        initStrategies(applicationContext);
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        initStrategies(applicationContext);
    }

    //網(wǎng)關(guān)啟動(dòng)時(shí)調(diào)用,設(shè)置三個(gè)list變量并排序
    protected void initStrategies(ApplicationContext context) {
        Map mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerMapping.class, true, false);

        ArrayList mappings = new ArrayList<>(mappingBeans.values());
        AnnotationAwareOrderComparator.sort(mappings);
        this.handlerMappings = Collections.unmodifiableList(mappings);

        Map adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerAdapter.class, true, false);

        this.handlerAdapters = new ArrayList<>(adapterBeans.values());
        AnnotationAwareOrderComparator.sort(this.handlerAdapters);

        Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                context, HandlerResultHandler.class, true, false);

        this.resultHandlers = new ArrayList<>(beans.values());
        AnnotationAwareOrderComparator.sort(this.resultHandlers);
    }


    @Override
    public Mono handle(ServerWebExchange exchange) {
        if (logger.isDebugEnabled()) {
            ServerHttpRequest request = exchange.getRequest();
            logger.debug("Processing " + request.getMethodValue() + " request for [" + request.getURI() + "]");
        }
        if (this.handlerMappings == null) {
            return Mono.error(HANDLER_NOT_FOUND_EXCEPTION);
        }
        return Flux.fromIterable(this.handlerMappings)
                //handlerMappings根據(jù)路由匹配合適的handler,確定是網(wǎng)關(guān)處理還是代理到第三方
                .concatMap(mapping -> mapping.getHandler(exchange))
                //上面的匹配可能會(huì)出現(xiàn)多個(gè)符合條件的,next()的作用在于匹配到第一個(gè)就停止匹配
                .next()
                .switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION))
                .flatMap(handler -> invokeHandler(exchange, handler))
                .flatMap(result -> handleResult(exchange, result));
    }

    private Mono invokeHandler(ServerWebExchange exchange, Object handler) {
        if (this.handlerAdapters != null) {
            for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
                if (handlerAdapter.supports(handler)) {//前面匹配到handler后,循環(huán)便利是否支持并執(zhí)行    
                    hadler方法
                    return handlerAdapter.handle(exchange, handler); 
                }
            }
        }
        return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
    }

    private Mono handleResult(ServerWebExchange exchange, HandlerResult result) {
        return getResultHandler(result).handleResult(exchange, result)
                .onErrorResume(ex -> result.applyExceptionHandler(ex).flatMap(exceptionResult ->
                        //同樣是循環(huán)遍歷是否支持并執(zhí)行  handleResult方法
                        getResultHandler(exceptionResult).handleResult(exchange, exceptionResult)));
    }

    private HandlerResultHandler getResultHandler(HandlerResult handlerResult) {
        if (this.resultHandlers != null) {
            for (HandlerResultHandler resultHandler : this.resultHandlers) {
                if (resultHandler.supports(handlerResult)) { 
                    return resultHandler;
                }
            }
        }
        throw new IllegalStateException("No HandlerResultHandler for " + handlerResult.getReturnValue());
    }

}

接上面 :

handlerAdapter.handle(exchange, handler); 
只說(shuō)匹配到我們配置的路由的情況
進(jìn)入到SimpleHandlerAdapter類(lèi)
public class SimpleHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(Object handler) {
        return WebHandler.class.isAssignableFrom(handler.getClass());
    }

    @Override
    public Mono handle(ServerWebExchange exchange, Object handler) {
        WebHandler webHandler = (WebHandler) handler;
        //根據(jù)傳進(jìn)來(lái)的不同handler處理不同的情況,匹配上路由的話(huà)傳進(jìn)來(lái)的是FilteringWebHandler
        Mono mono = webHandler.handle(exchange);
        return mono.then(Mono.empty());
    }

}
繼續(xù)看FilteringWebHandler類(lèi):

public class FilteringWebHandler implements WebHandler {
    protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);

    private final List globalFilters;
    //在GatewayAutoConfiguration中配置bean,注入所有實(shí)現(xiàn)GlobalFilter的類(lèi)
    public FilteringWebHandler(List globalFilters) {
        this.globalFilters = loadFilters(globalFilters);
    }
    //將GlobalFilter和GatewayFilter合并并排序
    private static List loadFilters(List filters) {
        return filters.stream()
                .map(filter -> {
                    GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
                    if (filter instanceof Ordered) {
                        int order = ((Ordered) filter).getOrder();
                        return new OrderedGatewayFilter(gatewayFilter, order);
                    }
                    return gatewayFilter;
                }).collect(Collectors.toList());
    }

    /* TODO: relocate @EventListener(RefreshRoutesEvent.class)
    void handleRefresh() {
        this.combinedFiltersForRoute.clear();
    }*/

    @Override
    public Mono handle(ServerWebExchange exchange) {
        //獲取前面在匹配路由時(shí)放進(jìn)ServerWebExchange中的路由數(shù)據(jù)
        Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
        //獲取本路由配置的過(guò)濾器
        List gatewayFilters = route.getFilters();

        List combined = new ArrayList<>(this.globalFilters);
        //把當(dāng)前路由的過(guò)濾器跟全局過(guò)濾器組合
        combined.addAll(gatewayFilters);
        //排序
        AnnotationAwareOrderComparator.sort(combined);

        if (logger.isDebugEnabled()) {
            logger.debug("Sorted gatewayFilterFactories: "+ combined);
        }

        return new DefaultGatewayFilterChain(combined).filter(exchange);
    }

    private static class DefaultGatewayFilterChain implements GatewayFilterChain {

        private final int index;
        private final List filters;

        public DefaultGatewayFilterChain(List filters) {
            this.filters = filters;
            this.index = 0;
        }

        private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
            this.filters = parent.getFilters();
            this.index = index;
        }

        public List getFilters() {
            return filters;
        }

        @Override
        public Mono filter(ServerWebExchange exchange) {
            return Mono.defer(() -> {
                if (this.index < filters.size()) {
                //與之前的WebFilter 一樣,每次執(zhí)行都new DefaultGatewayFilterChain調(diào)用filter方法,
                //不斷往下執(zhí)行直到過(guò)濾器走完
                    GatewayFilter filter = filters.get(this.index);
                    DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
                    return filter.filter(exchange, chain);
                } else {
                    return Mono.empty(); // complete
                }
            });
        }
    }

    private static class GatewayFilterAdapter implements GatewayFilter {

        private final GlobalFilter delegate;

        public GatewayFilterAdapter(GlobalFilter delegate) {
            this.delegate = delegate;
        }

        @Override
        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            return this.delegate.filter(exchange, chain);
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
            sb.append("delegate=").append(delegate);
            sb.append("}");
            return sb.toString();
        }
    }

}

然后,在排序倒數(shù)第二的過(guò)濾器NettyRoutingFilter中,調(diào)用默認(rèn)的HttpClient,代理到后面的服務(wù)。
至此,流程就走完了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/77400.html

相關(guān)文章

  • SpringCloud升級(jí)之路2020.0.x版-41. SpringCloudGateway 基本

    摘要:將請(qǐng)求封裝成將請(qǐng)求封裝成的接口定義是但是最外層傳進(jìn)來(lái)的參數(shù)是和,需要將他們封裝成,這個(gè)工作就是在中做的。其實(shí)主要任務(wù)就是將各種參數(shù)封裝成除了和本次請(qǐng)求相關(guān)的和,還有會(huì)話(huà)管理器,編碼解碼器配置,國(guó)際化配置還有用于擴(kuò)展。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent接下來(lái),將進(jìn)入我們升級(jí)之路的又一大模塊,即網(wǎng)關(guān)模塊。網(wǎng)關(guān)模塊我們廢棄了...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • spring cloud gateway 源碼解析(4)跨域問(wèn)題處理

    摘要:現(xiàn)在項(xiàng)目大多開(kāi)始前后端分離,前端開(kāi)發(fā)的時(shí)候可以用的來(lái)配置線(xiàn)上打包的話(huà)可以直接放到后臺(tái)項(xiàng)目的靜態(tài)資源目錄了,這樣就不會(huì)有跨域問(wèn)題,或者放到里在配置好資源目錄就行,這些方案網(wǎng)上都有就不展開(kāi)了,現(xiàn)在說(shuō)說(shuō)怎么處理跨域我們看類(lèi)里的方法根據(jù)獲取不同的后 現(xiàn)在項(xiàng)目大多開(kāi)始前后端分離,前端開(kāi)發(fā)的時(shí)候可以用webpack的proxytable來(lái)配置線(xiàn)上打包的話(huà)可以直接放到后臺(tái)項(xiàng)目的靜態(tài)資源目錄了,這樣就...

    Me_Kun 評(píng)論0 收藏0
  • Spring Cloud Gateway 擴(kuò)展支持動(dòng)態(tài)限流

    摘要:以流量為切入點(diǎn),從流量控制熔斷降級(jí)系統(tǒng)負(fù)載保護(hù)等多個(gè)維度保護(hù)服務(wù)的穩(wěn)定性分布式系統(tǒng)的流量防衛(wèi)兵。歡迎關(guān)注我們獲得更多的好玩實(shí)踐 之前分享過(guò) 一篇 《Spring Cloud Gateway 原生的接口限流該怎么玩》, 核心是依賴(lài)Spring Cloud Gateway 默認(rèn)提供的限流過(guò)濾器來(lái)實(shí)現(xiàn) 原生RequestRateLimiter 的不足 配置方式 spring: clou...

    妤鋒シ 評(píng)論0 收藏0
  • Spring Cloud Gateway 擴(kuò)展支持動(dòng)態(tài)限流

    摘要:以流量為切入點(diǎn),從流量控制熔斷降級(jí)系統(tǒng)負(fù)載保護(hù)等多個(gè)維度保護(hù)服務(wù)的穩(wěn)定性分布式系統(tǒng)的流量防衛(wèi)兵。歡迎關(guān)注我們獲得更多的好玩實(shí)踐 之前分享過(guò) 一篇 《Spring Cloud Gateway 原生的接口限流該怎么玩》, 核心是依賴(lài)Spring Cloud Gateway 默認(rèn)提供的限流過(guò)濾器來(lái)實(shí)現(xiàn) 原生RequestRateLimiter 的不足 配置方式 spring: clou...

    beanlam 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<