Talking about SpringCloud's zuul source code analysis, springcloudzuul

Source: Internet
Author: User

Talking about SpringCloud's zuul source code analysis, springcloudzuul

Zuul versions of the implementation of some minor changes, the overall implementation of the idea has not changed, take spring-cloud-netflix-core-1.3.6.RELEASE as an Example

1. Important initialization classes of zuul

Org. springframework. cloud. netflix. zuul. ZuulServerAutoConfiguration

Org. springframework. cloud. netflix. zuul. ZuulProxyAutoConfiguration

Org. springframework. cloud. netflix. zuul. ZuulFilterInitializer

Org. springframework. cloud. netflix. zuul. RibbonCommandFactoryConfiguration

ZuulServerAutoConfiguration

Initialize routing rules

Initialize important filters such as PreDecorationFilter and RibbonRoutingFilter.

Initialize ZuulFilterInitializer

Initialize ZuulHandlerMapping

The Code is as follows:

// Routing rule @ Bean @ ConditionalOnMissingBean (DiscoveryClientRouteLocator. class) public DiscoveryClientRouteLocator discoveryRouteLocator () {return new DiscoveryClientRouteLocator (this. server. getServletPrefix (), this. discovery, this. zuulProperties, this. serviceRouteMapper);} // pre filters @ Bean public PreDecorationFilter preDecorationFilter (RouteLocator routeLocator, ProxyRequestHelper proxyRequestHelp Er) {return new PreDecorationFilter (routeLocator, this. server. getServletPrefix (), this. zuulProperties, proxyRequestHelper);} // route filters @ Bean public RibbonRoutingFilter ribbonRoutingFilter (ProxyRequestHelper helper, RibbonCommandFactory <?> RibbonCommandFactory) {RibbonRoutingFilter filter = new RibbonRoutingFilter (helper, ribbonCommandFactory, this. requestCustomizers); return filter;} @ Configuration protected static class ZuulFilterConfiguration {@ Autowired private Map <String, ZuulFilter> filters; @ Bean public ZuulFilterInitializer initialize (CounterFactory counterFactory, TracerFactory tracerFactory) {FilterLoader filterLoader = FilterLoader. getInstance (); FilterRegistry filterRegistry = FilterRegistry. instance (); return new ZuulFilterInitializer (this. filters, counterFactory, tracerFactory, filterLoader, filterRegistry) ;}@ Bean public ZuulController zuulController () {return new ZuulController () ;}@ Bean public ZuulHandlerMapping zuulHandlerMapping (RouteLocator routes) {ZuulHandlerMapping mapping = new ZuulHandlerMapping (routes, zuulController (); mapping. setErrorController (this. errorController); return mapping ;}

ZuulProxyAutoConfiguration

ZuulProxAutoConfiguration inherits the ZuulServerAutoConfiguration function and zuulServerAutoConfiguration

The main function is to add the RibbonCommandFactoryConfiguration configuration and initialize all ribbon implementation methods, such as apache and okhttp.

ZuulFilterInitializer

This class is mainly used to register the initialized filter to zuul's FilterRegistry. FilterRegistry is a singleton used to initialize route information and is used in ZuulRunner.

RibbonCommandFactoryConfiguration

The main role is to configure the implementation of forwarding, including apache and okhttp.

Ii. zuul forwarding implementation

First, go to the lookupHandler method in ZuulHandlerMapping and forward it to zuulController.

@Override protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception { if (this.errorController != null && urlPath.equals(this.errorController.getErrorPath())) {  return null; } String[] ignored = this.routeLocator.getIgnoredPaths().toArray(new String[0]); if (PatternMatchUtils.simpleMatch(ignored, urlPath)) {  return null; } RequestContext ctx = RequestContext.getCurrentContext(); if (ctx.containsKey("forward.to")) {  return null; } if (this.dirty) {  synchronized (this) {  if (this.dirty) {   registerHandlers();   this.dirty = false;  }  } } return super.lookupHandler(urlPath, request); }

When dirty is true during the first access, the following request rules will be initialized:

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);  } } }

Step 2: When ZuulController inherits ServletWrappingController, the request will be forwarded to ZuulServlet as follows:

/** * @author Spencer Gibb */public class ZuulController extends ServletWrappingController { public ZuulController() { setServletClass(ZuulServlet.class); setServletName("zuul"); setSupportedMethods((String[]) null); // Allow all } @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { try {  // We don't care about the other features of the base class, just want to  // handle the request  return super.handleRequestInternal(request, response); } finally {  // @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter  RequestContext.getCurrentContext().unset(); } }}

Step 3: The ZuulServlet service method is as follows: Execute pre, route, and postRoute routers.

 @Override  public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {    try {      init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);      // Marks this request as having passed through the "Zuul engine", as opposed to servlets      // explicitly bound in web.xml, for which requests will not have the same data attached      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();    }  }

4. The final result is returned by SendResponseFilter, and filterOrder is 1000. Therefore, it is recommended that the filter of post should not exceed 1000; otherwise, the returned result will be affected.

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.