SpringCloud 之 Zuul源代码初识

Zuul 介绍

Zuul 处理 Http 请求都是基于 SpringMVC 上的,细心的你一定注意到了,当你搭建了一个zuul后配置后端隐射请求 /apps/** 到你的后端服务时,无论 /apps/**** 还是 /zuul/apps/**** 都能到达你的后端服务。

那么这到达是如何实现的呢?

ZuulServlet

Zuul 有一个自制的 Servlet -- ZuulServlet, 它包含了 Zuul 所有的处理流程的主干支,这里不详细介绍,以后会篇章会详细介绍 Zuul 的处理流程。

SpringBoot 有个 ServletRegistrationBean 是专门用来注册自定义 Servlet 的。

    public ServletRegistrationBean zuulServlet() {
		ServletRegistrationBean servlet = new ServletRegistrationBean(new ZuulServlet(),
				this.zuulProperties.getServletPattern());
		servlet.addInitParameter("buffer-requests", "false");
		return servlet;
	}

这里还有一个定义路基path 的使用,默认是 /zuul,你可以通过配置文件定义成其他,如下就改成 /api 了

zuul.servletPath=/api

如果没有使用 SpringBoot 的话,那么其实老办法只要将 ZuulServlet 配置在 web.xml 中即可,路径也是 web.xml 中配置。

ZuulHandlerMapping

来看下这个是哪门哪派的。

RequestMappingHandlerMapping 不会陌生,SpringMVC默认使用的就是这个,它会捕捉所有 @Controller@RequetMapping 注解的方法来处理不同的URL。

SpringMVC3.1之前其实不是使用上面这个类,而是使用 AbstractUrlHandlerMapping  的派系 -- DefaultAnnotationHandlerMapping,这个类可是 ZuulHandlerMapping 一个派系的,都是根据 URL 来选择使用使用什么来处理。

那到底用什么来处理呢?ZuulHandlerMappingregisterHandlers 方法回答了这个问题

	private void registerHandlers() {
		Collection<Route> routes = this.routeLocator.getRoutes();
		if (routes.isEmpty()) {
			this.logger.warn("No routes found from RouteLocator");
		}
		else {
			for (Route route : routes) {
				registerHandler(route.getFullPath(), this.zuul);
			}
		}
	}

this.zuul 是什么? ZuulController

public class ZuulController extends ServletWrappingController

原来是 Servlet 包装成 Controller, 其实还是 ZuulServlet

public class ZuulController extends ServletWrappingController {

	public ZuulController() {
		setServletClass(ZuulServlet.class); // <<======= See Here!
		setServletName("zuul");
		setSupportedMethods((String[]) null); // Allow all
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			return super.handleRequestInternal(request, response);
		}
		finally {
			RequestContext.getCurrentContext().unset();
		}
	}

}

小结:

Zuul 的 Request 怎么进来的到这已经清楚了,下面分析进来以后发生了什么。

详细代码解析见 SpringCloud 之 Zuul 源代码详细笔记

猜你喜欢

转载自my.oschina.net/alexqdjay/blog/1802502