最近是跳槽的高峰期,我连日加班好多天,整理出了包含16000 多道面试题的面试宝典,并且指北君也会持续更新这份面试宝典中的题目,希望它能帮助大家找到自己心仪的工作!【文末有领取方式】
在上篇中已经说过了 Eureka-Server 本质上是一个 web 应用的项目,今天就来看看 Spring Boot 是怎么启动 Eureka 的。
Spring Boot 启动 Eureka 流程
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
上面的代码是最最平常的 Spring Boot 启动类。Spring Boot 启动 eureka 的关键注解就在 @EnableEurekaServer 上面。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({EurekaServerMarkerConfiguration.class})
public @interface EnableEurekaServer {
}
可以看到这注解导入了一个 EurekaServerMarkerConfiguration 类。
@Configuration
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}
}
EurekaServerMarkerConfiguration 向 Spring 容器注入了一个 EurekaServerMarkerConfiguration.Marker 对象。Maker 是一个空对象,是一个标记开关的类。具体开关的类在上面的注释中。
/**
* Responsible for adding in a marker bean to activate
* {@link EurekaServerAutoConfiguration}
*
* @author Biju 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 的容器中。
public class EurekaServerInitializerConfiguration
implements ServletContextAware, SmartLifecycle, Ordered
-
ServletContextAware:实现这个类可以获取到 ServletContext 容器上下文。
-
SmartLifecycle:当 Spring 容器加载所有 bean 并完成初始化之后,会接着回调实现该接口的类中对应的 start() 方法
看一下 start() 方法里面调用了什么?
@Override
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
try {
eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);
log.info("Started Eureka Server");
publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
EurekaServerInitializerConfiguration.this.running = true;
publish(new EurekaServerStartedEvent(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() 方法。
public void contextInitialized(ServletContext context) {
try {
initEurekaEnvironment();
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);
}
}
contextInitialized 方法调用了 initEurekaEnvironment(),初始化 Eureka 的运行环境;initEurekaServerContext(),初始化 Eureka 的上下文。
总结
Spring Boot 启动 Erueka Server 经历了一下步骤:
-
@EnableEurekaServer 注解
-
注入了 EurekaServerMarkerConfiguration.Marker 对象
-
判断容器里是否有 EurekaServerMarkerConfiguration.Marker 对象注入了 EurekaServerAutoConfiguration
-
导入了实现 SmartLifecycle 接口的 EurekaServerInitializerConfiguration 类
-
Spring 容器在初始化后调用了 EurekaServerInitializerConfiguration 对象的 start() 方法
-
start() 中启动了一个线程,调用了 Erueka Server 的启动类:EurekaServerBootstrap。
面试大全包括:包括 Java 集合、JVM、多线程、并发编程、设计模式、SpringBoot、SpringCloud、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、Python、HTML、CSS、Vue、React、JavaScript、Android 大数据、阿里巴巴等大厂面试题等、等技术栈!
分享不易,如果觉得分享对大家有帮助,老规矩,点赞、关注、留言支持哦!