SpringCloudZuul源码解析-1

1. 创建项目 引入maven相关依赖

pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-dependencies</artifactId>
       <version>2.2.2.RELEASE</version>
   </parent>

   <groupId>org.example</groupId>
   <artifactId>ZuulSourceCodeParsing</artifactId>
   <version>1.0-SNAPSHOT</version>

   <properties>
       <maven.compiler.source>8</maven.compiler.source>
       <maven.compiler.target>8</maven.compiler.target>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
           <version>2.2.2.RELEASE</version>
       </dependency>
   </dependencies>

</project>

主类配置

package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

//开启zuul网关配置
@EnableZuulProxy
@SpringBootApplication
public class ZuulSourceCodeParsing {

   public static void main(String[] args) {
       SpringApplication.run(ZuulSourceCodeParsing.class);
   }
}

application.yml 配置

zuul:
  ignored-patterns: /test/**
  routes:
    myroute:
      url: http://localhost:8085/
      path: /test01/**
      id: test

2.@EnableZuulProxy分析

主要导入了 ZuulProxyMarkerConfiguration 的配置类

@EnableCircuitBreaker
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyMarkerConfiguration.class)
public @interface EnableZuulProxy {

}

ZuulProxyMarkerConfiguration 引入了 一个 Mark的bean

@Configuration(proxyBeanMethods = false)
public class ZuulProxyMarkerConfiguration {

	@Bean
	public Marker zuulProxyMarkerBean() {
		return new Marker();
	}

	class Marker {
	}
}

导入Marker之后会触发 一个配置类的自动装配ZuulProxyAutoConfiguration 类继承了 ZuulServerAutoConfiguration 进而引入了Zuul网关的所有组件

ZuulServerAutoConfiguration 类分析

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ ZuulProperties.class })
@ConditionalOnClass({ ZuulServlet.class, ZuulServletFilter.class })
@ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class)
public class ZuulServerAutoConfiguration {
   
    //zuul的核心配置累 包括路由,忽略请求path,请求头等
	@Autowired
	protected ZuulProperties zuulProperties;
     
     //获取springmvc 中的配置 里面包含 port等信息
	@Autowired
	protected ServerProperties server;
	
	//获取springmvc 异常 controller
	@Autowired(required = false)
	private ErrorController errorController;

	//跨域相关
	private Map<String, CorsConfiguration> corsConfigurations;
     
     //获取springmvc configurer配置类结合
	@Autowired(required = false)
	private List<WebMvcConfigurer> configurers = emptyList();

	@Bean
	public HasFeatures zuulFeature() {
		return HasFeatures.namedFeature("Zuul (Simple)",
				ZuulServerAutoConfiguration.class);
	}
   //复合的 路由器 里面包含多个RouteLocator 实现类
	@Bean
	@Primary
	public CompositeRouteLocator primaryRouteLocator(
			Collection<RouteLocator> routeLocators) {
		return new CompositeRouteLocator(routeLocators);
	}
     //基于zuul配置的 路由定位器
	@Bean
	@ConditionalOnMissingBean(SimpleRouteLocator.class)
	public SimpleRouteLocator simpleRouteLocator() {
		return new SimpleRouteLocator(this.server.getServlet().getContextPath(),
				this.zuulProperties);
	}
    
    //zuul的核心controller 后面会讲
	@Bean
	public ZuulController zuulController() {
		return new ZuulController();
	}
	
	//zuul继承springmvc的核心类 后面会讲
	@Bean
	public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes,
			ZuulController zuulController) {
		ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController);
		mapping.setErrorController(this.errorController);
		mapping.setCorsConfigurations(getCorsConfigurations());
		return mapping;
	}

	//跨域相关配置
	protected final Map<String, CorsConfiguration> getCorsConfigurations() {
		if (this.corsConfigurations == null) {
			ZuulCorsRegistry registry = new ZuulCorsRegistry();
			this.configurers.forEach(configurer -> configurer.addCorsMappings(registry));
			this.corsConfigurations = registry.getCorsConfigurations();
		}
		return this.corsConfigurations;
	}
	
	//注册zuul刷新监听器
	@Bean
	public ApplicationListener<ApplicationEvent> zuulRefreshRoutesListener() {
		return new ZuulRefreshListener();
	}

	//注册zuulservlet的bean
	@Bean
	@ConditionalOnMissingBean(name = "zuulServlet")
	@ConditionalOnProperty(name = "zuul.use-filter", havingValue = "false",
			matchIfMissing = true)
	public ServletRegistrationBean zuulServlet() {
		ServletRegistrationBean<ZuulServlet> servlet = new ServletRegistrationBean<>(
				new ZuulServlet(), this.zuulProperties.getServletPattern());
		servlet.addInitParameter("buffer-requests", "false");
		return servlet;
	}
    
    //注册zuul的 serveltFilter过滤器
	@Bean
	@ConditionalOnMissingBean(name = "zuulServletFilter")
	@ConditionalOnProperty(name = "zuul.use-filter", havingValue = "true",
			matchIfMissing = false)
	public FilterRegistrationBean zuulServletFilter() {
		final FilterRegistrationBean<ZuulServletFilter> filterRegistration = new FilterRegistrationBean<>();
		filterRegistration.setUrlPatterns(
				Collections.singleton(this.zuulProperties.getServletPattern()));
		filterRegistration.setFilter(new ZuulServletFilter());
		filterRegistration.setOrder(Ordered.LOWEST_PRECEDENCE);
		filterRegistration.addInitParameter("buffer-requests", "false");
		return filterRegistration;
	}

	// pre类型filter也就是发送请求前 一些准备工作
	@Bean
	public ServletDetectionFilter servletDetectionFilter() {
		return new ServletDetectionFilter();
	}

	@Bean
	@ConditionalOnMissingBean
	public FormBodyWrapperFilter formBodyWrapperFilter() {
		return new FormBodyWrapperFilter();
	}

	@Bean
	@ConditionalOnMissingBean
	public DebugFilter debugFilter() {
		return new DebugFilter();
	}

	@Bean
	@ConditionalOnMissingBean
	public Servlet30WrapperFilter servlet30WrapperFilter() {
		return new Servlet30WrapperFilter();
	}

	// post类型filters 发送完请求之后
	@Bean
	public SendResponseFilter sendResponseFilter(ZuulProperties properties) {
		return new SendResponseFilter(zuulProperties);
	}
	
	@Bean
	public SendErrorFilter sendErrorFilter() {
		return new SendErrorFilter();
	}

	@Bean
	public SendForwardFilter sendForwardFilter() {
		return new SendForwardFilter();
	}

	@Bean
	@ConditionalOnProperty("zuul.ribbon.eager-load.enabled")
	public ZuulRouteApplicationContextInitializer zuulRoutesApplicationContextInitiazer(
			SpringClientFactory springClientFactory) {
		return new ZuulRouteApplicationContextInitializer(springClientFactory,
				zuulProperties);
	}

	@Configuration(proxyBeanMethods = false)
	protected static class ZuulFilterConfiguration {
		@Autowired
		private Map<String, ZuulFilter> 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);
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(MeterRegistry.class)
	protected static class ZuulCounterFactoryConfiguration {

		@Bean
		@ConditionalOnBean(MeterRegistry.class)
		@ConditionalOnMissingBean(CounterFactory.class)
		public CounterFactory counterFactory(MeterRegistry meterRegistry) {
			return new DefaultCounterFactory(meterRegistry);
		}

	}

	@Configuration(proxyBeanMethods = false)
	protected static class ZuulMetricsConfiguration {
		@Bean
		@ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry")
		@ConditionalOnMissingBean(CounterFactory.class)
		public CounterFactory counterFactory() {
			return new EmptyCounterFactory();
		}
		@ConditionalOnMissingBean(TracerFactory.class)
		@Bean
		public TracerFactory tracerFactory() {
			return new EmptyTracerFactory();
		}
	}
    //zuul配置类结合 apollo nacos配置中心自动刷新
	private static class ZuulRefreshListener
			implements ApplicationListener<ApplicationEvent> {
		@Autowired
		private ZuulHandlerMapping zuulHandlerMapping;
		private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();
		
		//对事件进行判断
		@Override
		public void onApplicationEvent(ApplicationEvent event) {
			if (event instanceof ContextRefreshedEvent
					|| event instanceof RefreshScopeRefreshedEvent
					|| event instanceof RoutesRefreshedEvent
					|| event instanceof InstanceRegisteredEvent) {
				reset();
			}
			else if (event instanceof ParentHeartbeatEvent) {
				ParentHeartbeatEvent e = (ParentHeartbeatEvent) event;
				resetIfNeeded(e.getValue());
			}
			else if (event instanceof HeartbeatEvent) {
				HeartbeatEvent e = (HeartbeatEvent) event;
				resetIfNeeded(e.getValue());
			}
		}
		private void resetIfNeeded(Object value) {
			if (this.heartbeatMonitor.update(value)) {
				reset();
			}
		}
		private void reset() {
			this.zuulHandlerMapping.setDirty(true);
		}

	}

    //zuul跨越相关配置
	private static class ZuulCorsRegistry extends CorsRegistry {
		@Override
		protected Map<String, CorsConfiguration> getCorsConfigurations() {
			return super.getCorsConfigurations();
		}
	}
}

ZuulProxyAutoConfiguration 自动装配类

@Configuration(proxyBeanMethods = false)
@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class,
		RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class,
		RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class,
		HttpClientConfiguration.class })
@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class)
public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration {

	//自定义的 ribbon请求
	@Autowired(required = false)
	private List<RibbonRequestCustomizer> requestCustomizers = Collections.emptyList();
   
   //注册器 如果引入nacos或者其他注册中心后 会有具体实现类
	@Autowired(required = false)
	private Registration registration;
	
	//服务发现客服端
	@Autowired
	private DiscoveryClient discovery;
	
	//接口 根据serviceId 获取具体的url 默认实现为 SimpleServiceRouteMapper
	@Autowired
	private ServiceRouteMapper serviceRouteMapper;

	@Override
	public HasFeatures zuulFeature() {
		return HasFeatures.namedFeature("Zuul (Discovery)",
				ZuulProxyAutoConfiguration.class);
	}
	
	//服务发现路由器 配置注册中心使用
	@Bean
	@ConditionalOnMissingBean(DiscoveryClientRouteLocator.class)
	public DiscoveryClientRouteLocator discoveryRouteLocator() {
		return new DiscoveryClientRouteLocator(this.server.getServlet().getContextPath(),
				this.discovery, this.zuulProperties, this.serviceRouteMapper,
				this.registration);
	}

	// pre类型的 filter
	@Bean
	@ConditionalOnMissingBean(PreDecorationFilter.class)
	public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator,
			ProxyRequestHelper proxyRequestHelper) {
		return new PreDecorationFilter(routeLocator,
				this.server.getServlet().getContextPath(), this.zuulProperties,
				proxyRequestHelper);
	}

	// route类型的filter
	@Bean
	@ConditionalOnMissingBean(RibbonRoutingFilter.class)
	public RibbonRoutingFilter ribbonRoutingFilter(ProxyRequestHelper helper,
			RibbonCommandFactory<?> ribbonCommandFactory) {
		RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, ribbonCommandFactory,
				this.requestCustomizers);
		return filter;
	}	
	
	//简单的 host route 通过http实现调用
	@Bean
	@ConditionalOnMissingBean({ SimpleHostRoutingFilter.class,
			CloseableHttpClient.class })
	public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper,
			ZuulProperties zuulProperties,
			ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
			ApacheHttpClientFactory httpClientFactory) {
		return new SimpleHostRoutingFilter(helper, zuulProperties,
				connectionManagerFactory, httpClientFactory);
	}
·
	@Bean
	@ConditionalOnMissingBean({ SimpleHostRoutingFilter.class })
	public SimpleHostRoutingFilter simpleHostRoutingFilter2(ProxyRequestHelper helper,
			ZuulProperties zuulProperties, CloseableHttpClient httpClient) {
		return new SimpleHostRoutingFilter(helper, zuulProperties, httpClient);
	}
	//服务路由 mapper 根据注册中心servicId获取 调用的url
	@Bean
	@ConditionalOnMissingBean(ServiceRouteMapper.class)
	public ServiceRouteMapper serviceRouteMapper() {
		return new SimpleServiceRouteMapper();
	}
	//心跳配置相关
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingClass("org.springframework.boot.actuate.health.Health")
	protected static class NoActuatorConfiguration {

		@Bean
		public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) {
			ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties);
			return helper;
		}
	}
}

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值