zuul源码分析

来源:互联网 发布:中英文对照阅读软件 编辑:程序博客网 时间:2024/05/29 12:28

使用zuulFilter时不知道这个run的返回值干嘛的,于是决定看下源码:

根据相关文档得知:

zuul的入口是zuulservlet:

我们可以看到重写了service

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {        try {            this.init((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse);            RequestContext context = RequestContext.getCurrentContext();            context.setZuulEngineRan();            try {                this.preRoute();            } catch (ZuulException var13) {                this.error(var13);                this.postRoute();                return;            }            try {                this.route();            } catch (ZuulException var12) {                this.error(var12);                this.postRoute();                return;            }            try {                this.postRoute();            } catch (ZuulException var11) {                this.error(var11);            }        } catch (Throwable var14) {            this.error(new ZuulException(var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass().getName()));        } finally {            RequestContext.getCurrentContext().unset();        }    }
发现route、postRoute和preRoute跟进发现最终调用filterProcessor中的runFilters方法:

public Object runFilters(String sType) throws Throwable {        if(RequestContext.getCurrentContext().debugRouting()) {            Debug.addRoutingDebug("Invoking {" + sType + "} type filters");        }        boolean bResult = false;        List<ZuulFilter> list = FilterLoader.getInstance().getFiltersByType(sType);        if(list != null) {            for(int i = 0; i < list.size(); ++i) {                ZuulFilter zuulFilter = (ZuulFilter)list.get(i);                Object result = this.processZuulFilter(zuulFilter);                if(result != null && result instanceof Boolean) {                    bResult |= ((Boolean)result).booleanValue();                }            }        }        return Boolean.valueOf(bResult);    }

那么processZuulFilter方法是干什么的呢?

public Object processZuulFilter(ZuulFilter filter) throws ZuulException {        RequestContext ctx = RequestContext.getCurrentContext();        boolean bDebug = ctx.debugRouting();        String metricPrefix = "zuul.filter-";        long execTime = 0L;        String filterName = "";        try {            long ltime = System.currentTimeMillis();            filterName = filter.getClass().getSimpleName();            RequestContext copy = null;            Object o = null;            Throwable t = null;            if(bDebug) {                Debug.addRoutingDebug("Filter " + filter.filterType() + " " + filter.filterOrder() + " " + filterName);                copy = ctx.copy();            }            ZuulFilterResult result = filter.runFilter();            ExecutionStatus s = result.getStatus();            execTime = System.currentTimeMillis() - ltime;            switch(null.$SwitchMap$com$netflix$zuul$ExecutionStatus[s.ordinal()]) {            case 1:                t = result.getException();                ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);                break;            case 2:                o = result.getResult();                ctx.addFilterExecutionSummary(filterName, ExecutionStatus.SUCCESS.name(), execTime);                if(bDebug) {                    Debug.addRoutingDebug("Filter {" + filterName + " TYPE:" + filter.filterType() + " ORDER:" + filter.filterOrder() + "} Execution time = " + execTime + "ms");                    Debug.compareContextState(filterName, copy);                }            }            if(t != null) {                throw t;            } else {                this.usageNotifier.notify(filter, s);                return o;            }        } catch (Throwable var15) {            if(bDebug) {                Debug.addRoutingDebug("Running Filter failed " + filterName + " type:" + filter.filterType() + " order:" + filter.filterOrder() + " " + var15.getMessage());            }            this.usageNotifier.notify(filter, ExecutionStatus.FAILED);            if(var15 instanceof ZuulException) {                throw (ZuulException)var15;            } else {                ZuulException ex = new ZuulException(var15, "Filter threw Exception", 500, filter.filterType() + ":" + filterName);                ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);                throw ex;            }        }    }
这些式源码。。。有点长,挑重点:

ZuulFilterResult result = filter.runFilter();
...
o = result.getResult();
...
return o;
就是这句话。返回了结果。(ZuulFilterResult的细节自己去看

那么就是说

this.processZuulFilter(zuulFilter);

filter.runFilter().getResult()返回了那么这个getResult是什么呢?

ZuulFilter.runFilter()的源代码中这样写的:

public ZuulFilterResult runFilter() {        ZuulFilterResult zr = new ZuulFilterResult();        if(!this.isFilterDisabled()) {            if(this.shouldFilter()) {                Tracer t = TracerFactory.instance().startMicroTracer("ZUUL::" + this.getClass().getSimpleName());                try {                    Object res = this.run();                    zr = new ZuulFilterResult(res, ExecutionStatus.SUCCESS);                } catch (Throwable var7) {                    t.setName("ZUUL::" + this.getClass().getSimpleName() + " failed");                    zr = new ZuulFilterResult(ExecutionStatus.FAILED);                    zr.setException(var7);                } finally {                    t.stopAndLog();                }            } else {                zr = new ZuulFilterResult(ExecutionStatus.SKIPPED);            }        }
this.run()是什么?是你自己实现的filter中的run方法啊。

所以你的返回值在ZuulFilter.runFilter()封装成了

ZuulFilterResult
然后在FilterProcessor.processZuulFilter()又解封为

result

然后做了一步这样的操作。

for(int i = 0; i < list.size(); ++i) {                ZuulFilter zuulFilter = (ZuulFilter)list.get(i);                Object result = this.processZuulFilter(zuulFilter);                if(result != null && result instanceof Boolean) {                    bResult |= ((Boolean)result).booleanValue();                }            }
那么就是说它期待result式boolean类型的。

但是最终用到那里了呢?

public void postRoute() throws ZuulException {        try {            this.runFilters("post");        } catch (ZuulException var2) {            throw var2;        } catch (Throwable var3) {            throw new ZuulException(var3, 500, "UNCAUGHT_EXCEPTION_IN_POST_FILTER_" + var3.getClass().getName());        }    }    public void error() {        try {            this.runFilters("error");        } catch (Throwable var2) {            logger.error(var2.getMessage(), var2);        }    }    public void route() throws ZuulException {        try {            this.runFilters("route");        } catch (ZuulException var2) {            throw var2;        } catch (Throwable var3) {            throw new ZuulException(var3, 500, "UNCAUGHT_EXCEPTION_IN_ROUTE_FILTER_" + var3.getClass().getName());        }    }    public void preRoute() throws ZuulException {        try {            this.runFilters("pre");        } catch (ZuulException var2) {            throw var2;        } catch (Throwable var3) {            throw new ZuulException(var3, 500, "UNCAUGHT_EXCEPTION_IN_PRE_FILTER_" + var3.getClass().getName());        }    }
What???

然后我选择了返回null。

有点忙先看到这,其他的以后补上。




未完待续...

参考:

http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/1.2.7.RELEASE/点击打开链接

http://blog.csdn.net/haha7289/article/details/54312043点击打开链接

http://www.cnblogs.com/lexiaofei/p/7080257.html点击打开链接