Zull实际上就是一个servlet,一个网关的servlet。
public class ZuulServlet extends HttpServlet {
private static final long serialVersionUID = -3374242278843351500L;
private ZuulRunner zuulRunner;
@Override
public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
try {
init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
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();
}
}
...
...
ZullServlet的service就走3个,一个pre,一个route,一个post。分别是前置,分发,后置。
但不管是pre还是route,最终都走到了FilterProcessor类里,它里面的一些方法都这样:
public void preRoute() throws ZuulException {
try {
runFilters("pre");
} catch (ZuulException e) {
throw e;
} catch (Throwable e) {
throw new ZuulException(e, 500, "UNCAUGHT_EXCEPTION_IN_PRE_FILTER_" + e.getClass().getName());
}
}
这明显就是抽象出来。里面是一个方法实现的,只是参数不一样,如下:
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 = list.get(i);
Object result = processZuulFilter(zuulFilter);
if (result != null && result instanceof Boolean) {
bResult |= ((Boolean) result);
}
}
}
return bResult;
}
由此可以看出来,先获取到各种类型的过滤器集合,然后分别执行他们。
如果我们有自己自定义的filter,那么也在其中。
怎么自定义,则集成Zullfilter即可,重写方法
@Override
public String filterType() {
return "pre";
}@Override
public void run() {
//业务
}
这就代表着是个前置的过滤器。
值得注意的是,pre-type的zullfilter集合里,最后一个永远是org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter。
该filter通过requestURI来分解获得servicename,然后保存起来,并供route-type的filter使用分发