ZuulServlet是HttpServlet。Servlet的生命週期包括init(僅第一次)、service、destroy。ZuulServlet的init在Zuul- 啓動提過了,就是建立一個ZuulRunner對象。因此咱們主要看service方法java
這個方法就是獲取一個RequestContext,若是沒有則建立,是ThreadLocal類。獲取後就開始調用preRoute、route、postRoute、error方法。因爲這幾個方法調用方式是一致的,因此下面就只講preRoute,這個方法實際就是調用ZuulRunner#preRoute方法。segmentfault
@Override public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException { try { // 給RequestContext賦值request和HttpResponse init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); // 獲取RequestContext RequestContext context = RequestContext.getCurrentContext(); context.setZuulEngineRan(); 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(); } }
preRoute是單例。而後調用runFilters。在runFilters中,先從FilterLoader獲取ZuulFilter集合,而後遍歷處理ZuulFilter。ide
public void preRoute() throws ZuulException { runFilters("pre"); //其餘略 } public Object runFilters(String sType) throws Throwable { boolean bResult = false; // 從FilterLoader獲取ZuulFilter集合 List<ZuulFilter> list = FilterLoader.getInstance().getFiltersByType(sType); if (list != null) { for (int i = 0; i < list.size(); i++) { ZuulFilter zuulFilter = list.get(i); // 處理每一個ZuulFilter Object result = processZuulFilter(zuulFilter); if (result != null && result instanceof Boolean) { bResult |= ((Boolean) result); } } } return bResult; }
FilterLoader也是單例。主要就是ConcurrentHashMap類型的hashFiltersByType取值,沒有的話從filterRegistry獲取,而後排序返回。post
public List<ZuulFilter> getFiltersByType(String filterType) { // 從ConcurrentHashMap類型的hashFiltersByType,經過filterType取ZuulFilter集合 List<ZuulFilter> list = hashFiltersByType.get(filterType); // 若是有了,直接返回 if (list != null) return list; list = new ArrayList<ZuulFilter>(); //沒有從filterRegistry獲取,並根據filterType拿到對應的ZuulFilter Collection<ZuulFilter> filters = filterRegistry.getAllFilters(); for (Iterator<ZuulFilter> iterator = filters.iterator(); iterator.hasNext(); ) { ZuulFilter filter = iterator.next(); if (filter.filterType().equals(filterType)) { list.add(filter); } } // 排序 Collections.sort(list); // sort by priority hashFiltersByType.putIfAbsent(filterType, list); return list; }
拿到ZuulFilter集合後,對每一個ZuulFilter處理。主要的調用ZuulFilter的runFilter方法。this
public Object processZuulFilter(ZuulFilter filter) throws ZuulException { // 其餘略 ZuulFilterResult result = filter.runFilter(); // 其餘略 }
public ZuulFilterResult runFilter() { ZuulFilterResult zr = new ZuulFilterResult(); // 是否配置禁用,"zuul." + this.getClass().getSimpleName() + "." + filterType() + ".disable" // 好比zuul.PreDecorationFilter.pre.disable=false if (!isFilterDisabled()) { // 這個是咱們須要寫的,是否過濾 if (shouldFilter()) { Tracer t = TracerFactory.instance().startMicroTracer("ZUUL::" + this.getClass().getSimpleName()); try { // 這個是咱們須要寫的run方法 Object res = run(); zr = new ZuulFilterResult(res, ExecutionStatus.SUCCESS); } catch (Throwable e) { t.setName("ZUUL::" + this.getClass().getSimpleName() + " failed"); zr = new ZuulFilterResult(ExecutionStatus.FAILED); zr.setException(e); } finally { t.stopAndLog(); } } else { zr = new ZuulFilterResult(ExecutionStatus.SKIPPED); } } return zr; }
ZuulServlet#service中,經過各個ZuulServlet進行相關處理。
spa