在上篇中已经说过了 Eureka-Server 本质上是一个 web 应用的项目,今天就来看看 Spring Boot 是怎么启动 Eureka 的。
Spring Boot 启动 Eureka 流程
@SpringBootApplication@EnableEurekaServerpublic class EurekaServer {publicstaticvoidmain(String[] args) {SpringApplication.run(EurekaServer.class, args); } }
上面的代码是最最平常的 Spring Boot 启动类。Spring Boot 启动 eureka 的关键注解就在 @EnableEurekaServer 上面。
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Import({EurekaServerMarkerConfiguration.class}) public@interfaceEnableEurekaServer { }
可以看到这注解导入了一个 EurekaServerMarkerConfiguration 类。
@ConfigurationpublicclassEurekaServerMarkerConfiguration{@BeanpublicMarkereurekaServerMarkerBean(){returnnewMarker(); }classMarker{ } }
EurekaServerMarkerConfiguration 向 Spring 容器注入了一个 EurekaServerMarkerConfiguration.Marker 对象。Maker 是一个空对象,是一个标记开关的类。具体开关的类在上面的注释中。
/** * Responsible foradding in a marker bean toactivate * {@linkEurekaServerAutoConfiguration} * *@authorBiju Kunjummen */
EurekaServerMarkerConfiguration.Marker 对象用于激活 EurekaServerAutoConfiguration 类。
那 EurekaServerAutoConfiguration 类是在什么时候加载的呢?
org.springframework.boot.autoconfigure.EnableAutoConfiguration= org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration
如上图,EurekaServerAutoConfiguration 启动的调用是在 spring.factories 中的,在 Spring Boot 的启动过程中,会加载所有的 spring.factories。这个时候会读取并加载里面的内容到 Spring 中。
- @Import(EurekaServerInitializerConfiguration.class):初始化 EurekaServerAutoConfiguration 的时候会导入 EurekaServerInitializerConfiguration 类。
- @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class):当 Spring 中有 EurekaServerMarkerConfiguration.Marker 类的实例存在就把 EurekaServerAutoConfiguration 也导入到 Spring 的容器中。
publicclassEurekaServerInitializerConfigurationimplementsServletContextAware, SmartLifecycle, Ordered
- ServletContextAware:实现这个类可以获取到 ServletContext 容器上下文。
- SmartLifecycle:当 Spring 容器加载所有 bean 并完成初始化之后,会接着回调实现该接口的类中对应的 start() 方法
看一下 start() 方法里面调用了什么?
@Overridepublicvoidstart(){newThread(newRunnable(){@Overridepublicvoidrun(){try{ eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext); log.info("Started Eureka Server"); publish(newEurekaRegistryAvailableEvent(getEurekaServerConfig())); EurekaServerInitializerConfiguration.this.running =true; publish(newEurekaServerStartedEvent(getEurekaServerConfig())); }catch(Exception ex) {// Help!log.error("Could not initialize Eureka servlet context", ex); } } }).start(); }
start() 启动了一个线程,在线程里面 Start 了 Eureka Server。eurekaServerBootstrap 是一个自动注入 EurekaServerBootstrap 的对象。EurekaServerBootstrap 在上一篇中已经说过了,它是 Eureka Server 的启动类。最后看看它的 contextInitialized() 方法。
publicvoidcontextInitialized(ServletContext context) {try{ initEurekaEnvironment(); initEurekaServerContext(); context.setAttribute(EurekaServerContext.class.getName(), this.serverContext); }catch(Throwablee) { log.error("Cannot bootstrap eureka server :", e);thrownewRuntimeException("Cannot bootstrap eureka server :", e); } }
contextInitialized 方法调用了 initEurekaEnvironment(),初始化 Eureka 的运行环境;initEurekaServerContext(),初始化 Eureka 的上下文。
总结
Spring Boot 启动 Erueka Server 经历了一下步骤:
- @EnableEurekaServer 注解
- 注入了 EurekaServerMarkerConfiguration.Marker 对象
- 判断容器里是否有 EurekaServerMarkerConfiguration.Marker 对象注入了 EurekaServerAutoConfiguration
- 导入了实现 SmartLifecycle 接口的 EurekaServerInitializerConfiguration 类
- Spring 容器在初始化后调用了 EurekaServerInitializerConfiguration 对象的 start() 方法
- start() 中启动了一个线程,调用了 Erueka Server 的启动类:EurekaServerBootstrap。
- Web
+关注
关注
2文章
1250浏览量
68981 - 容器
+关注
关注
0文章
485浏览量
21963 - eureka
+关注
关注
0文章
4浏览量
1755 - SpringBoot
+关注
关注
0文章
172浏览量
141
发布评论请先登录
相关推荐
评论