Spring Cloud 源码分析之 Eureka 篇第二章:注册中心启动类上的注解 EnableEurekaServer

497 篇文章 2 订阅
495 篇文章 0 订阅

欢迎访问我的 GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

  • 本章是《Spring Cloud 源码分析》系列文章的第二篇,我们从注册中心 Eureka 开始这段历程;

Spring Cloud 源码下载

启动类上的注解

package com.bolingcavalry.springclouddeepeureka;
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication@EnableEurekaServerpublic class SpringclouddeepeurekaApplication {
    public static void main(String[] args) {        SpringApplication.run(SpringclouddeepeurekaApplication.class, args);    }}

复制代码

  • 上面这段代码与一般的 SpringBoot 启动类不同之处在于多了个注解 @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 {
}

复制代码

  • 上述代码中,注解 @Import(EurekaServerMarkerConfiguration.class) 表示,EurekaServerMarkerConfiguration 这个类也会被作为 bean 做实例化;另外请注意注释中的内容: 注解 EnableEurekaServer 用来激活 Eureka Server 相关的配置:EurekaServerAutoConfiguration ,记下这是 EurekaServerAutoConfiguration 第一次出现在我们面前;

  • 接下来去看被实例化了的 EurekaServerMarkerConfiguration 的源码:

/** * Responsible for adding in a marker bean to activate * {@link EurekaServerAutoConfiguration} * * @author Biju Kunjummen */@Configurationpublic class EurekaServerMarkerConfiguration {
  @Bean  public Marker eurekaServerMarkerBean() {    return new Marker();  }
  class Marker {  }}

复制代码

  • 如上所示,简单到只有个一内部类 EurekaServerMarkerConfiguration.Marker,我的猜测是: 有的 bean 会通过注解 ConditionalOnBean 作为自己是否实例化的条件,而条件对应的 bean 就是 EurekaServerMarkerConfiguration.Marker ;

  • 请注意注释中的内容: 注解 EurekaServerMarkerConfiguration 用来响应激活 EurekaServerAutoConfiguration ,这是 EurekaServerAutoConfiguration 第二次出现在我们面前;

  • 根据前面两次注释的提示,EurekaServerAutoConfiguration 类是必须要看了,打开这个类,先看注解:

@Configuration@Import(EurekaServerInitializerConfiguration.class)@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)@EnableConfigurationProperties({ EurekaDashboardProperties.class,    InstanceRegistryProperties.class })@PropertySource("classpath:/eureka/server.properties")

复制代码

  • 符合之前的猜测,通过 @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) 注解,保证了 EurekaServerAutoConfiguration 类会被实例化后注册到 spring 容器中,也就是说这里面的配置都生效了;

  • 接下来就是 spring 容器对 bean 进行实例化和初始化了,重点需要关注的是 EurekaServerInitializerConfiguration、EurekaServerContext、EurekaServerBootstrap 这三个类;

  • EurekaServerAutoConfiguration 中的 @Bean 注解会实例化 EurekaServerContext、EurekaServerBootstrap,这两个实例已经不是 SpringCloud 工程的内容了,它们都来自 com.netflix.eureka ,它们接手了真正的 EurekaServer 的启动逻辑:

@Beanpublic EurekaServerContext eurekaServerContext(ServerCodecs serverCodecs,    PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) {  return new DefaultEurekaServerContext(this.eurekaServerConfig, serverCodecs,      registry, peerEurekaNodes, this.applicationInfoManager);}
@Beanpublic EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry,    EurekaServerContext serverContext) {  return new EurekaServerBootstrap(this.applicationInfoManager,      this.eurekaClientConfig, this.eurekaServerConfig, registry,      serverContext);}

复制代码

  • EurekaServerInitializerConfiguration 这个类出现在 EurekaServerAutoConfiguration 的注解中,通过 @Import 注解被实例化,由于实现了 Lifecycle 接口,因此会被 spring 容器回调 start 方法:

@Overridepublic void start() {  new Thread(new Runnable() {    @Override    public void run() {      try {        //TODO: is this class even needed now?        eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);        log.info("Started Eureka Server");
        //发送广播,将EurekaServer的配置信息广播给全部订阅了该类型消息的监听        publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));        EurekaServerInitializerConfiguration.this.running = true;        //发送广播,将EurekaServer的配置信息广播给全部订阅了该类型消息的监听        publish(new EurekaServerStartedEvent(getEurekaServerConfig()));      }      catch (Exception ex) {        // Help!        log.error("Could not initialize Eureka servlet context", ex);      }    }  }).start();}

复制代码

  • 如上所示,EurekaServerInitializerConfiguration 初始化的时候,除了主动调用 bootstrap 的初始化方法,还通过广播将 eureka 的配置信息发出去;

  • eureka 的配置信息 EurekaServerConfig 来自何处呢?EurekaServerAutoConfiguration 的内部类 EurekaServerConfigBeanConfiguration 负责生成这些配置信息,实例类型为 EurekaServerConfigBean:

@Configurationprotected static class EurekaServerConfigBeanConfiguration {  @Bean  @ConditionalOnMissingBean  public EurekaServerConfig eurekaServerConfig(EurekaClientConfig clientConfig) {    EurekaServerConfigBean server = new EurekaServerConfigBean();    if (clientConfig.shouldRegisterWithEureka()) {      // Set a sensible default if we are supposed to replicate      server.setRegistrySyncRetries(5);    }    return server;  }}

复制代码

  • 至此,我们对 EnableEurekaServer 注解有了更深入的了解,虽然创建注册中心所需代码很少,但是背后隐藏着复杂的初始化服务,感谢大师们杰出的设计,封装了复杂逻辑,让业务测可以轻量级完成这些操作;

欢迎关注 InfoQ:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值