ZuulServlet是HttpServlet。Servlet的生命周期包括init(仅第一次)、service、destroy。ZuulServlet的init在Zuul- 启动提过了,就是创建一个ZuulRunner对象。所以我们主要看service方法
ZuulServlet#service
这个方法就是获取一个RequestContext,如果没有则创建,是ThreadLocal类。获取后就开始调用preRoute、route、postRoute、error方法。由于这几个方法调用方式是一致的,所以下面就只讲preRoute,这个方法实际就是调用ZuulRunner#preRoute方法。
@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();
}
}
ZuulRunner#preRoute
preRoute是单例。然后调用runFilters。在runFilters中,先从FilterLoader获取ZuulFilter集合,然后遍历处理ZuulFilter。
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#getFiltersByType
FilterLoader也是单例。主要就是ConcurrentHashMap类型的hashFiltersByType取值,没有的话从filterRegistry获取,然后排序返回。
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;
}
FilterProcessor#processZuulFilter
拿到ZuulFilter集合后,对每个ZuulFilter处理。主要的调用ZuulFilter的runFilter方法。
public Object processZuulFilter(ZuulFilter filter) throws ZuulException {
// 其他略
ZuulFilterResult result = filter.runFilter();
// 其他略
}
ZuulFilter#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进行相关处理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。