:注册中心启动类上的注解EnableEurekaServer

Posted 程序员欣宸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了:注册中心启动类上的注解EnableEurekaServer相关的知识,希望对你有一定的参考价值。

欢迎访问我的GitHub

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

Spring Cloud源码下载

启动类上的注解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplicationbr/>@EnableEurekaServer
public class SpringclouddeepeurekaApplication

public static void main(String[] args) 
    SpringApplication.run(SpringclouddeepeurekaApplication.class, args);


- 上面这段代码与一般的SpringBoot启动类不同之处在于多了个注解==@EnableEurekaServer==,今天的源码分析都是围绕这个类开展的;

1. 看看此注解的源码:
```java
/**
 * 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第一次出现在我们面前;
  1. 接下来去看被实例化了的EurekaServerMarkerConfiguration的源码:

    /**
    * Responsible for adding in a marker bean to activate
    * @link EurekaServerAutoConfiguration
    *
    * @author Biju Kunjummen
    */
    @Configuration
    public class EurekaServerMarkerConfiguration 
    
    @Bean
    public Marker eurekaServerMarkerBean() 
        return new Marker();
    
    
    class Marker 
    
    
    • 如上所示,简单到只有个一内部类EurekaServerMarkerConfiguration.Marker,我的猜测是:==有的bean会通过注解ConditionalOnBean作为自己是否实例化的条件,而条件对应的bean就是EurekaServerMarkerConfiguration.Marker==;
  • 请注意注释中的内容:==注解EurekaServerMarkerConfiguration 用来响应激活EurekaServerAutoConfiguration==,这是EurekaServerAutoConfiguration第二次出现在我们面前;
  1. 根据前面两次注释的提示,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容器中,也就是说这里面的配置都生效了;

  2. 接下来就是spring容器对bean进行实例化和初始化了,重点需要关注的是EurekaServerInitializerConfiguration、EurekaServerContext、EurekaServerBootstrap这三个类;
  3. EurekaServerAutoConfiguration中的@Bean注解会实例化EurekaServerContext、EurekaServerBootstrap,这两个实例已经不是SpringCloud工程的内容了,它们都来自==com.netflix.eureka==,它们接手了真正的EurekaServer的启动逻辑:
    
    @Bean
    public EurekaServerContext eurekaServerContext(ServerCodecs serverCodecs,
        PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) 
    return new DefaultEurekaServerContext(this.eurekaServerConfig, serverCodecs,
            registry, peerEurekaNodes, this.applicationInfoManager);
    

@Bean
public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry,
EurekaServerContext serverContext)
return new EurekaServerBootstrap(this.applicationInfoManager,
this.eurekaClientConfig, this.eurekaServerConfig, registry,
serverContext);


6. EurekaServerInitializerConfiguration这个类出现在EurekaServerAutoConfiguration的注解中,通过@Import注解被实例化,由于实现了Lifecycle接口,因此会被spring容器回调start方法:
```java
@Override
public 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:

    @Configuration
    protected 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注解有了更深入的了解,虽然创建注册中心所需代码很少,但是背后隐藏着复杂的初始化服务,感谢大师们杰出的设计,封装了复杂逻辑,让业务测可以轻量级完成这些操作;

欢迎关注51CTO博客:程序员欣宸

以上是关于:注册中心启动类上的注解EnableEurekaServer的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot项目主启动类上常用的注解释意

SpringCloud --- 服务注册中心 (EurekaZookeeperConsul)

SpringCloud --- 服务注册中心 (EurekaZookeeperConsul)

java如何获取类上的注解

获取指定类上的@RequestMapping注解的请求信息

父类上的注解能被子类继承吗