SpringCloud resolve the Zuul (b)

Based on the Spring Cloud Edgware.SR6, Zuul version 1.3.1, the resolution request interception mechanism Zuul, so that we have a general knowledge and understanding of the principles of Zuul. If wrong, please correct me.

On one of SpringCloud Zuul parsing of (a) , we understand the spring boot after receiving a request gateway, it is how to find a matching ZuulHandlerMapping. Today, we continue to explore how to deal with this ZuulHandlerMapping gateway request.

Before we start, let's look at why such a large spring boot to the trouble, only to find ZuulHandlerMapping.

By the last article, we know that all browser requests will arrive DispatcherServlet, and DispatcherServlet has a member variable handlerMappings, scans all HandlerMapping inherited interface implementation class, in fact, that there is also a member variable handlerAdapters, this variable will scan HandlerAdapter class that implements all interfaces. As can be seen from the name, contains all of the processors HandlerAdapters adapters, all HandlerMapping are performed by its corresponding HandlerAdapter is, the purpose of decoupling. Because after this design, DispatcherServlet HandlerMapping and will not include specific logic code does not need to be concerned about what type of request, just call the corresponding HandlerAdapter approach it.

What ZuulHandlerMapping inside it? ZuulHandlerMapping has a member variable ZuulController, ZuulController inherited ServletWrappingController, ServletWrappingController there servletClass and servletInstance.

image

image

image

On the one beginning, I had a rough mention, in spring boot startup process initializes ZuulController, followed by reflection initialization ZuulServlet. In detail, the spring boot is initialized during startup will automatically configure org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration zuul by category, including ZuulHandlerMapping. So, ZuulHandlerMapping there ZuulController, ZuulController there ZuulServlet, after these object instances have a successful start in spring boot.

image

image

Well, after this knowledge, we are moving on today. DispatcherServlet.doDispatch () after acquiring the ZuulHandlerMapping, immediately call the method getHandlerAdapter () Gets corresponding HandlerAdapter.

image

image

Can be seen, getHandlerAdapter () internally traversing handlerAdapters, which acquires supported handlerAdapter foregoing handler processor then determines the Supports by calling a respective () method. It is taken herein to SimpleControllerHandlerAdapter.

After taking into handlerAdapter, start calling handlerAdapter the handle () method, mappedHandler.getHandler () is ZuulController. SimpleControllerHandlerAdapter.handle () inside, is ZuulController.handleRequest (), its interior is calling handleRequestInternal parent class (), the real work is servletInstance.service (), but it is servletInstance ZuulServlet (we mentioned at the beginning)

image

image

image

image

Let's look, ZuulServlet.service () does.

public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
    try {
        // 初始化,将servletRequest和servletResponse存储到请求上下文RequestContext
        init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);

        // Marks this request as having passed through the "Zuul engine", as opposed to servlets
        // explicitly bound in web.xml, for which requests will not have the same data attached
        RequestContext context = RequestContext.getCurrentContext();
        context.setZuulEngineRan();
        // 顺序执行ZuulFilter过滤器,也包括我们继承ZuulFilter的自定义过滤器
        try {
            preRoute();
        } catch (ZuulException e) {
            error(e);
            postRoute();
            return;
        }
        try {
            route();
        } catch (ZuulException e) {
            error(e);
            postRoute();
            return;
        }
        try {
            postRoute();
        } catch (ZuulException e) {
            error(e);
            return;
        }

    } catch (Throwable e) {
        error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
    } finally {
        RequestContext.getCurrentContext().unset();
    }
}

简直一目了然。我们往下看,它是如何会执行我们继承ZuulFilter的自定义过滤器。(上文忘了说,在ZuulServlet实例化后,会调用init()方法初始化ZuulRunner)。

image

image

以preRoute()为例,不难看出,最终的执行者是FilterProcessor,在runFilters()方法中,获取对应类型的List<ZuulFilter>,然后遍历执行processZuulFilter(zuulFilter)

image

image

image

image

FilterLoader.getInstance().getFiltersByType(sType)内容如下,就是从hashFiltersByType中获取filterType对应的List<ZuulFilter>
image

image

那么新问题就来了,hashFiltersByType里的值怎么来的。FilterLoader还有一个putFilter(File file)方法,通过查找源码很容易发现,这个方法是在FilterFileManager中被调用的。官方的解释是,FilterFileManager类负责初始化和更新filter(但是我一直搞不懂它是如何调用运行的,因为我打断点都没有效果,猜测是Groovy,不甚了解,知道的小伙伴帮忙评论解释下,感激不尽)。

INSTANCE.manageFiles () call is the final FilterLoader.putFilter () method, INSTANCE.startPoller () is to start a daemon thread, polling execution manageFiles ().

image

image

image

image

Looking back, we continue to see processZuulFilter (zuulFilter) did what. Amount, in fact, the key to the following sentence,

image

ZuulFilter.runFilter () method first determines! IsFilterDisabled (), shouldFilter (), execution run () method when satisfied, i.e., the configuration file isFilter not disabled, and returns true custom filters shouldFilter (), will ZuulFilter of rewriting execution run () method.

image

Thus, zuul gateway performs custom filters and filter process is finished (ah, exhausted).

Finally, to sum up:

1.spring boot adapter design pattern by using corresponding HandlerAdapter performed ZuulHandlerMapping, for the purpose of decoupling. The ZuulHandlerMapping ultimately ZuulServlet.service call ()

2.ZuulServlet.service () inside, but also remove all types of ZuulFilter filterType, then traverse the execution run ZuulFilter () method, which is why we write custom filters to inherit the cause of ZuulFilter.

Next, we have to talk about Zuul on the request filtering is how to forward the request to the corresponding server.

Guess you like

Origin www.cnblogs.com/wangl110/p/11222763.html