In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
What is the Zuul Filter of zuul in Springcloud, many beginners are not very clear about it. In order to help you solve this problem, the following editor will explain it in detail. People with this need can come and learn. I hope you can get something.
The version of Springcloud is Greenwich.SR2,Springboot and the version is 2.1.6.release.
Recently used Springcloud's zuul, analyzed the source code and recorded it.
Here is the List-1. The ZuulFilter we define inherits the zuulFilter of zuul, then defines it as Bean, and delivers it to the Spring container:
List-1
/ / pass the filter to Spring management @ Beanpublic AuthFilter authFilter () {return new AuthFilter ();} / / xss filter @ Beanpublic XssFilter xssFilter () {return new XssFilter ();} @ Beanpublic HelloZuulFilter firewallFilter () {return new HelloZuulFilter ();} @ Beanpublic HelloInfoFilter helloInfoFilter () {return new HelloInfoFilter ();}
After looking at the ZuulServerAutoConfiguration, the following List-2,@Autowired private Map filters fetches all the ZuulFilter from the Spring container, and then passes in the filters when the ZuulFilterInitializer is instantiated.
List-2
... @ Configurationprotected static class ZuulFilterConfiguration {@ Autowired private Map filters; @ Bean public ZuulFilterInitializer zuulFilterInitializer (CounterFactory counterFactory, TracerFactory tracerFactory) {FilterLoader filterLoader = FilterLoader.getInstance (); FilterRegistry filterRegistry = FilterRegistry.instance (); return new ZuulFilterInitializer (this.filters, counterFactory, tracerFactory, filterLoader, filterRegistry);}}.
The following List-3
FilterRegistry is an attribute type, and @ PostConstruct is added to the contextInitialized method, so Spring will call this method after creating the Bean. After traversing the filters and putting it into the filterRegistry, there is an attribute of type ConcurrentHashMap in the filterRegistry, and these filter are put into this ConcurrentHashMap.
The method contextDestroyed is annotated with @ PreDestroy, and then iterates through the filters to remove it from the filterRegistry.
List-3
Public class ZuulFilterInitializer {private static final Log log = LogFactory.getLog (ZuulFilterInitializer.class); private final Map filters; private final CounterFactory counterFactory; private final TracerFactory tracerFactory; private final FilterLoader filterLoader; private final FilterRegistry filterRegistry; public ZuulFilterInitializer (Map filters, CounterFactory counterFactory, TracerFactory tracerFactory, FilterLoader filterLoader, FilterRegistry filterRegistry) {this.filters = filters This.counterFactory = counterFactory; this.tracerFactory = tracerFactory; this.filterLoader = filterLoader; this.filterRegistry = filterRegistry;} @ PostConstruct public void contextInitialized () {log.info ("Starting filter initializer"); TracerFactory.initialize (tracerFactory); CounterFactory.initialize (counterFactory) For (Map.Entry entry: this.filters.entrySet ()) {filterRegistry.put (entry.getKey (), entry.getValue ());} @ PreDestroy public void contextDestroyed () {log.info ("Stopping filter initializer") For (Map.Entry entry: this.filters.entrySet ()) {filterRegistry.remove (entry.getKey ());} clearLoaderCache (); TracerFactory.initialize (null); CounterFactory.initialize (null);}.
By default, ZuulServlet or ZuulServletFilter will be injected into the Spring container. If zuul.use-filter is set to true, ZuulServletFilter is used, but zuul.use-filter is not set by default, so ZuulServlet is used. The following List-4,ZuulServlet inherits HttpServlet and is a Servlet, and then gives it to ServletRegistrationBean to put the ZuulServlet in the web container.
List-4
. @ Bean@ConditionalOnMissingBean (name = "zuulServlet") @ ConditionalOnProperty (name = "zuul.use-filter", havingValue = "false", matchIfMissing = true) public ServletRegistrationBean zuulServlet () {ServletRegistrationBean servlet = new ServletRegistrationBean (new ZuulServlet (), this.zuulProperties.getServletPattern ()); / / The whole point of exposing this servlet is to provide a route that doesn't / / buffer requests. Servlet.addInitParameter ("buffer-requests", "false"); return servlet;} @ Bean@ConditionalOnMissingBean (name = "zuulServletFilter") @ ConditionalOnProperty (name = "zuul.use-filter", havingValue = "true", matchIfMissing = false) public FilterRegistrationBean zuulServletFilter () {final FilterRegistrationBean filterRegistration = new FilterRegistrationBean (); filterRegistration.setUrlPatterns (Collections.singleton (this.zuulProperties.getServletPattern ()); filterRegistration.setFilter (new ZuulServletFilter ()); filterRegistration.setOrder (Ordered.LOWEST_PRECEDENCE)) / / The whole point of exposing this servlet is to provide a route that doesn't / / buffer requests. FilterRegistration.addInitParameter ("buffer-requests", "false"); return filterRegistration;}.
The service method of ZuulServlet is as follows, first calling the preRoute () method, then route (), and finally postRoute (). The preRoute method calls zuulRunner.preRoute (), the preRoute () method of ZuulRunner calls FilterProcessor.getInstance () .preRoute (), and then goes deep into the preRoute method of FilterProcessor
List-5
Public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {try {this.init ((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); RequestContext context = RequestContext.getCurrentContext (); context.setZuulEngineRan (); try {this.preRoute ();} catch (ZuulException var13) {this.error (var13); this.postRoute (); return } try {this.route ();} catch (ZuulException var12) {this.error (var12); this.postRoute (); return;} try {this.postRoute ();} catch (ZuulException var11) {this.error (var11) } catch (Throwable var14) {this.error (new ZuulException (var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass (). GetName ());} finally {RequestContext.getCurrentContext (). Unset ();}} void postRoute () throws ZuulException {this.zuulRunner.postRoute ();} void route () throws ZuulException {this.zuulRunner.route ();} void preRoute () throws ZuulException {this.zuulRunner.preRoute ();}
The code in FilterProcessor's preRoute () is as follows: List-6, call the runFilters method, fetch all the ZuulFilter whose filterType is pre from FilterRegistry, sort it, and then call the runFilter method of ZuulFilter one by one-- in the method processZuulFilter. ZuulFilter is an abstract class. The run method is called in the runFilter method, and the run method is an abstract method, which is implemented by our custom, as shown in the following List-7
List-6
... public void preRoute () throws ZuulException {try {this.runFilters ("pre");} catch (ZuulException var2) {throw var2;} catch (Throwable var3) {throw new ZuulException (var3, 500, "UNCAUGHT_EXCEPTION_IN_PRE_FILTER_" + var3.getClass (). GetName ()) } public Object runFilters (String sType) throws Throwable {if (RequestContext.getCurrentContext (). DebugRouting ()) {Debug.addRoutingDebug ("Invoking {" + sType + "} type filters");} boolean bResult = false; List list = FilterLoader.getInstance (). GetFiltersByType (sType); if (list! = null) {for (int I = 0; I < list.size (); + + I) {ZuulFilter zuulFilter = (ZuulFilter) list.get (I) Object result = this.processZuulFilter (zuulFilter); if (result! = null & & result instanceof Boolean) {bResult | = (Boolean) result;} return bResult;} public Object processZuulFilter (ZuulFilter filter) throws ZuulException {RequestContext ctx = RequestContext.getCurrentContext (); boolean bDebug = ctx.debugRouting (); String metricPrefix = "zuul.filter-"; long execTime = 0L; String filterName = "" Try {long ltime = System.currentTimeMillis (); filterName = filter.getClass (). GetSimpleName (); RequestContext copy = null; Object o = null; Throwable t = null; if (bDebug) {Debug.addRoutingDebug ("Filter" + filter.filterType () + "+ filter.filterOrder () +" + filterName); copy = ctx.copy () } ZuulFilterResult result = filter.runFilter (); ExecutionStatus s = result.getStatus (); execTime = System.currentTimeMillis ()-ltime; switch (s) {case FAILED: t = result.getException (); ctx.addFilterExecutionSummary (filterName, ExecutionStatus.FAILED.name (), execTime); break; case SUCCESS: o = result.getResult () Ctx.addFilterExecutionSummary (filterName, ExecutionStatus.SUCCESS.name (), execTime); if (bDebug) {Debug.addRoutingDebug ("Filter {" + filterName + "TYPE:" + filter.filterType () + "ORDER:" + filter.filterOrder () + "} Execution time =" + execTime + "ms"); Debug.compareContextState (filterName, copy) }} if (t! = null) {throw t;} else {this.usageNotifier.notify (filter, s); return o } catch (Throwable var15) {if (bDebug) {Debug.addRoutingDebug ("Running Filter failed" + filterName + "type:" + filter.filterType () + "order:" + filter.filterOrder () + "" + var15.getMessage ());} this.usageNotifier.notify (filter, ExecutionStatus.FAILED); if (var15 instanceof ZuulException) {throw (ZuulException) var15 } else {ZuulException ex = new ZuulException (var15, "Filter threw Exception", 500, filter.filterType () + ":" + filterName); ctx.addFilterExecutionSummary (filterName, ExecutionStatus.FAILED.name (), execTime); throw ex;}.
As shown in List-7 below, the run method is called with try catch. If the run method throws an exception, it is regarded as a failure, and the ExecutionStatus of ZuulFilterResult is set to FAILED. Therefore, it does not matter what value the run method we implemented returns. The important thing is not to throw an exception. If an exception is thrown, it is regarded as a processing failure.
List-7
Public ZuulFilterResult runFilter () {ZuulFilterResult zr = new ZuulFilterResult (); if (! this.isFilterDisabled ()) {if (this.shouldFilter ()) {Tracer t = TracerFactory.instance (). StartMicroTracer ("ZUUL::" + this.getClass (). GetSimpleName ()); try {Object res = this.run (); zr = new ZuulFilterResult (res, ExecutionStatus.SUCCESS) } catch (Throwable var7) {t.setName ("ZUUL::" + this.getClass (). GetSimpleName () + "failed"); zr = new ZuulFilterResult (ExecutionStatus.FAILED); zr.setException (var7);} finally {t.stopAndLog () }} else {zr = new ZuulFilterResult (ExecutionStatus.SKIPPED);}} return zr;}
It is important to note that the FilterRegistry mentioned above all refer to the same static variable, so the transfer of each invocation relationship can still ensure thread safety.
Private static final FilterRegistry INSTANCE = new FilterRegistry ()
It should be noted that ZuulServlet and ZuulServletFilter handle requests with url for / zuul/*, see List-4 's this.zuulProperties.getServletPattern (), whose value is / zuul, and then use the ServletRegistration.Dynamic 's addMapping method to add the processed url to / zuul/*.
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.