这是我参与更文挑战的第8天,活动详情查看:更文挑战
一、前言
对应
eureka-server
详细源码分析: 链接
spring-cloud-starter-eureka-server
项目,就是对 eureka-server
进行了封装的 spring boot
项目。对应的官网:github.com/spring-clou…
既然都学习了 eureka-server
了,为什么还要学习 spring-cloud-starter-eureka-server
?
- 学习
spring-cloud
如何封装eureka-server
- 学习
spring-cloud
如何启动eureka-server
spring boot
集成 eureka-server
只需要加个注解 @EnableEurekaServer
,代码如下:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
提前小结
问题:
spring-cloud
如何封装eureka-server
?spring-cloud
如何启动eureka-server
?
1. spring-cloud
如何启动 eureka-server
?
启动主要分为两大步:
-
spring boot
启动后,将内嵌tomcat
容器启动,把自身作为一个web
应用启动 -
跟着
@EnableEurekaServer
注解,完成初始化,从而实现原来Bootstrap
:-
EurekaServerAutoConfiguration
初始化 -
EurekaServerInitializerConfiguration
初始化 -
EurekaServerBootstrap
: 对应着eureka-server
初始化
-
以上第二大步完成 eureka server
的所有组件的初始化,并将 eukrea server
启动。
2. 学习 spring-cloud
如何封装 eureka-server
?
最容易想到的是,直接拷贝代码。
但拷贝代码,又要减少耦合,保证个模块独立性,那么就需要
spring boot
的特征自动装配。
步骤可分为:
- 将
eureka-server
初始化代码,进行了封装: - 利用
spring boot
的特性,改写代码:bean
的生成、配置的加载 - 将
eureka-server
的配置文件打包:将配置集成进application.yml
,并赋值对应默认值
二、直接怼源码
着手点就是
@EnableEurekaServer
。
@EnableEurekaServer
注解:就是在spring boot
将自身的web
容器启动之后,再把eureka-server
启动起来。
从 @EnableEurekaServer
入手,主要看三个类,也可叫为三个步骤:
EurekaServerAutoConfiguration
初始化EurekaServerInitializerConfiguration
初始化- 重要:
EurekaServerBootstrap
初识化
在 IDEA
中按 CTRL + 点击
进入 @EnableEurekaServer
,源码如下:
/**
* Annotation to activate Eureka Server related configuration {@link EurekaServerAutoConfiguration}
*
* @author Dave Syer
* @author Biju Kunjummen
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EurekaServerMarkerConfiguration.class)
public @interface EnableEurekaServer {
}
EurekaServerAutoConfiguration
初始化
@EnableEurekaServer
会触发 EurekaServerAutoConfiguration
初始化,代码如下:
@Configuration // 标识是配置类
// 先执行,并生成对应的 bean
@Import(EurekaServerInitializerConfiguration.class)
// 当 Marker 对象被初始化并加载到 spring 容器中,这个配置才能加载
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
// 从配置文件加载配置信息到这两个 bean 中
@EnableConfigurationProperties({ EurekaDashboardProperties.class,
InstanceRegistryProperties.class })
// 加载默认配置文件
@PropertySource("classpath:/eureka/server.properties")
// 继承,目的将 eureka-server 的 jersey 拦截器信息注册到 springmvc 中
public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter {
// 初始化一大堆 eureka server 组件
// 并将这些组件生成对应 bean,加载进 spring 容器中
... ...
}
EurekaServerInitializerConfiguration
初始化
@Import(EurekaServerInitializerConfiguration.class)
,看类名就知道是初始化配置,其源码如下:
@Configuration
public class EurekaServerInitializerConfiguration
implements ServletContextAware, SmartLifecycle, Ordered {
// 值得说明的一点:SmartLifecycle ,在 bean 加载初始化完成之后,会调用其 start() 方法。
// 注入一堆 bean
... ...
// 通过实现 SmartLifecycle,在 spring 生命周期调用
@Override
public void start() {
// 另起一线程运行
new Thread(new Runnable() {
@Override
public void run() {
try {
// 重要:初始化 eureka-server
eurekaServerBootstrap.contextInitialized(
EurekaServerInitializerConfiguration.this.servletContext);
... ...
}
catch (Exception ex) {
... ...
}
}
}).start();
}
}
EurekaServerBootstrap
初始化
这块就可以对照
eureka-server
源码分析来看啦!!!
public class EurekaServerBootstrap {
public void contextInitialized(ServletContext context) {
try {
// 1. 初始化环境变量
initEurekaEnvironment();
// 2. 初始化上下文
initEurekaServerContext();
context.setAttribute(EurekaServerContext.class.getName(), this.serverContext);
}
catch (Throwable e) {
log.error("Cannot bootstrap eureka server :", e);
throw new RuntimeException("Cannot bootstrap eureka server :", e);
}
}
}