Spring Cloud Netflix Eureka Server源码分析之预热篇

905 阅读5分钟

微信公众号:I am CR7
如有问题或建议,请在下方留言;
最近更新:2018-11-25

如何使用

  • 引入maven依赖:
1<dependency>
2    <groupId>org.springframework.cloud</groupId>
3    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
4    <version>2.0.2.RELEASE</version>
5</dependency>
  • 启动类添加@EnableEurekaServer注解
1@EnableEurekaServer
2@SpringBootApplication
3public class EurekaServerApplication {
4
5    public static void main(String[] args) {
6        SpringApplication.run(EurekaServerApplication.class, args);
7    }
8}

通过上述两个步骤,我们就能启动一个eureka server。接下来,笔者会从这两个方面来进行进一步分析,让大家明白这背后的故事。

spring-cloud-starter-netflix-eureka-server

项目结构

我们来看下第一部分中引入的依赖包spring-cloud-starter-netflix-eureka-server【本例采用2.0.2.RELEASE版本】项目结构图:

image
image

一看上图,没有任何代码,只有pom文件和spring.provides文件。当时一想,肯定又是该死的网络导致包没下载全。删除本地仓库后reimport一次,还是这样。无奈,去github上看下源码,这到底是怎么回事。OMG!!!这就是项目原本的模样。

Why???

原来,spring-cloud-starter-*是为了通过starter对项目的依赖进行统一的管理,利用maven的传递依赖解析机制,将netflix-eureka-server相关的依赖库聚合到一起,从而实现针对特定功能来定制依赖的starter。spring.provides文件提供了pom更新的上下文。

友情链接:What are spring-boot-starter jars?

pom文件

请看pom文件的内容:

 1<dependencies>
2    <dependency>
3        <groupId>org.springframework.cloud</groupId>
4        <artifactId>spring-cloud-starter</artifactId>
5    </dependency>
6    <dependency>
7        <groupId>org.springframework.cloud</groupId>
8        <artifactId>spring-cloud-netflix-eureka-server</artifactId>
9    </dependency>
10    <dependency>
11        <groupId>org.springframework.cloud</groupId>
12        <artifactId>spring-cloud-starter-netflix-archaius</artifactId>
13    </dependency>
14    <dependency>
15        <groupId>org.springframework.cloud</groupId>
16        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
17    </dependency>
18    <dependency>
19        <groupId>com.netflix.ribbon</groupId>
20        <artifactId>ribbon-eureka</artifactId>
21    </dependency>
22</dependencies>

恭喜你,顺利找到了netflix eureka server的关键jar包:spring-cloud-netflix-eureka-server。

@EnableEurekaServer

请看源码:

1@Target(ElementType.TYPE)
2@Retention(RetentionPolicy.RUNTIME)
3@Documented
4@Import(EurekaServerMarkerConfiguration.class)
5public @interface EnableEurekaServer {
6
7}

@Import注解会导入EurekaServerMarkerConfiguration类,构建bean实例。

看一眼EurekaServerMarkerConfiguration的源码:

 1@Configuration
2public class EurekaServerMarkerConfiguration {
3
4    @Bean
5    public Marker eurekaServerMarkerBean() {
6        return new Marker();
7    }
8
9    class Marker {
10    }
11}
What???

这个类要做什么?创建了一个Marker的实例。别急,此处留个悬念,咱们继续往下看。

小结

通过在启动类中添加@EnableEurekaServer注解,会创建EurekaServerMarkerConfiguration的bean实例。

spring-cloud-netflix-eureka-server

项目结构

image
image

根据SpringBoot自动加载原理,它会在对SpringApplication对象实例化时自动加载META-INF/spring.factories文件,将该配置文件中指定的配置类载入到Spring容器。
我们来看下该文件的内容:

1org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2  org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration

小结

通过在pom文件中引入spring-cloud-starter-netflix-eureka-server包,当我们启动springboot容器时,会自动加载到spring-cloud-netflix-eureka-server项目里的META-INF/spring.factories文件,从而自动加载该文件中指定的配置类EurekaServerAutoConfiguration。

EurekaServerAutoConfiguration

1@Configuration
2@Import(EurekaServerInitializerConfiguration.class)
3@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
4@EnableConfigurationProperties({ EurekaDashboardProperties.class,
5        InstanceRegistryProperties.class })
6@PropertySource("classpath:/eureka/server.properties")
7public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter {
8    //省略
9}

此处只保留类声明部分代码,内部细节会在下一篇文章中详细分析。

我们来看@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)

@ConditionOnBean注解表示当spring容器中存在指定class类对应的实例时才会加载当前的这个bean。

也就是说加载EurekaServerAutoConfiguration这个bean的前提是spring
容器中必须有EurekaServerMarkerConfiguration.Marker的实例。根据上述小结我们知道,@EnableEurekaServer注解正是完成了这件事情。

小结

回顾我们前面遗留下的那个问题:"EurekaServerMarkerConfiguration有什么用"?
通过上述的分析,有没有发现这样一个逻辑:

  • netflix eureka server核心配置类是EurekaServerAutoConfiguration,其加载的前提----->先构建EurekaServerMarkerConfiguration.Marker实例
  • EurekaServerMarkerConfiguration.Marker实例前提----->先构建EurekaServerMarkerConfiguration实例
  • EurekaServerMarkerConfiguration实例是通过在EnableEurekaServer类中@Import导入的,必须得先用@EnableEurekaServer注解

所以,@EnableEurekaServer注解成为了开启netflix eureka server神秘大门的"钥匙"。

总结

本文作为预热篇,从如何使用入手,根据对依赖包和注解这两个方面的分析,让大家明白启用一个netflix eureka server需要具备的条件和内部实现的原理。 后续会逐步对netflix eureka server和client的内部实现原理进行深入分析,欢迎大家多多关注。