spring-eureka 在springCloud是类似于 zookeeper的存在,主要负责服务的注册发现。

1   由于是Servlet应用,所以Eureka需要通过servlet的相关监听器 ServletContextListener 嵌入到 Servlet 的生命周期中。EurekaBootStrap 类实现了该接口,在servlet标准的contextInitialized()方法中完成了初始化工作:

@Override
public void contextInitialized(ServletContextEvent event) {
try {
// 读取配置信息
initEurekaEnvironment();
// 初始化Eureka Client(用来与其它节点进行同步)
// 初始化server
initEurekaServerContext(); ServletContext sc = event.getServletContext();
sc.setAttribute(EurekaServerContext.class.getName(), serverContext);
} catch (Throwable e) {
logger.error("Cannot bootstrap eureka server :", e);
throw new RuntimeException("Cannot bootstrap eureka server :", e);
}
}

2 与Spring Cloud结合的胶水代码

Eureka是一个纯正的Servlet应用,而Spring Boot使用的是嵌入式Tomcat, 因此就需要一定的胶水代码让Eureka跑在Embedded Tomcat中。这部分工作是在 EurekaServerBootstrap 中完成的。与上面提到的EurekaBootStrap相比,它的代码几乎是直接将原生代码copy过来的,虽然它并没有继承 ServletContextListener, 但是相应的生命周期方法都还在,然后添加了@Configuration注解使之能被Spring容器感知:

 
原生的 EurekaBootStrap 类实现了标准的ServletContextListener接口

 
Spring Cloud的EurekaServerBootstrap类没有实现servlet接口,但是保留了接口方法的完整实现

我们可以推测,框架一定是在某处调用了这些方法,然后才是执行原生Eureka的启动逻辑。EurekaServerInitializerConfiguration类证实了我们的推测。该类实现了 ServletContextAware(拿到了tomcat的ServletContext对象)、SmartLifecycle(Spring容器初始化该bean时会调用相应生命周期方法):

@Configuration
@CommonsLog
public class EurekaServerInitializerConfiguration
implements ServletContextAware, SmartLifecycle, Ordered {
}

在 start() 方法中可以看到

eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);

的调用,也就是说,在Spring容器初始化该组件时,Spring调用其生命周期方法start()从而触发了Eureka的启动。

@Override
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
try {
eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext); // 调用 servlet 接口方法手工触发启动
log.info("Started Eureka Server"); // ... ...
}
catch (Exception ex) {
// Help!
log.error("Could not initialize Eureka servlet context", ex);
}
}
}).start();
}


最新文章

  1. Windows 服务的安装(1)
  2. apache 配虚拟主机转发到tomcat
  3. Websocket 协议解析
  4. django-redis和redis-py
  5. JavaScript格式化时间
  6. Hibernate三种状态的转换
  7. Swift:网络库Alamofire
  8. 【转】WCF和ASP.NET Web API在应用上的选择
  9. String中的Indexof,LastIndexOf, Indexofany,LastIndexOfAny 的区别
  10. C--指针数组
  11. ab返回结果参数分析
  12. bzoj:1941: [Sdoi2010]Hide and Seek
  13. JQuery的Ajax技术
  14. ☆ [洛谷P2633] Count on a tree 「树上主席树」
  15. 安装elasticsearch-7.0.0(centos)
  16. centos6.5 MySQL数据库的安装
  17. C语言函数声明什么时候可以省略,什么时候不能省?
  18. 踩坑rosbag --clock
  19. 网络3-Jsonp
  20. Shell-9--条件测试

热门文章

  1. 转 Spring 组件 <context:component-scan base-pakage="">用法
  2. Redis——慢查询分析
  3. HTML5/CSS3超酷环形动画菜单
  4. BA优化PnP的思路
  5. HDU 1032 The 3n + 1 problem (这个题必须写博客)
  6. C# 操作SQLServer SMO中遇到的几个问题
  7. python的join()函数
  8. Android Studio 代码混淆(你真的会混淆吗)
  9. checkbox怎么判断是否选中
  10. 查看linux连接进程占用的实时流量 -nethogs