美文网首页Spring
源码剖析 启动Eureka Server(一)@EnableEu

源码剖析 启动Eureka Server(一)@EnableEu

作者: 爱迪生玛玛 | 来源:发表于2018-10-29 15:59 被阅读225次

    Spring Cloud Netflix Eureka项目将Netflix公司的Eureka项目加以封装,以适配Spring Boot自动化配置的机制,通过注解在Spring Boot项目启动时启动Eureka Server。
    我们通过阅读相关源码,看看这一过程是如何实现的。


    回顾我们的eureka-demo中的eureka-server项目,在我们的项目启动类Server上有一个@EnableEurekaServer注解。

    @SpringBootApplication
    @EnableEurekaServer
    public class Server {
        //...
    }
    

    查看这个注解的定义

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(EurekaServerMarkerConfiguration.class)
    public @interface EnableEurekaServer {
    }
    

    可以看到它Import导入了EurekaServerMarkerConfiguration类

    @Configuration
    public class EurekaServerMarkerConfiguration {
        @Bean
        public Marker eurekaServerMarkerBean() {
            return new Marker();
        }
        class Marker {
        }
    }
    

    这个EurekaServerMarkerConfiguration会往Spring容器中注入一个eurekaServerMarkerBean,这个Marker是一个空类,那在这里起到什么作用呢?
    仔细查看这个类的注释,可以看到它只是一个开关标记,用来激活EurekaServerAutoConfiguration类的。

    /**
     * Responsible for adding in a marker bean to activate
     * {@link EurekaServerAutoConfiguration}
     *
     * @author Biju Kunjummen
     */
    

    查看EurekaServerAutoConfiguration类的定义

    @Configuration
    @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
    @EnableConfigurationProperties({ EurekaDashboardProperties.class,
            InstanceRegistryProperties.class })
    @PropertySource("classpath:/eureka/server.properties")
    public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter
    
    • @Configuration注解表示这是一个配置类,通过@Bean注解声明一些注入到Spring IOC容器中的Bean。
    • @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class),表示只要Spring容器中有EurekaServerMarkerConfiguration.Marker.class类的实例存在,那么就会将这个EurekaServerAutoConfiguration也注入到Spring容器中。
    • @Import(EurekaServerInitializerConfiguration.class)表明它导入了EurekaServerInitializerConfiguration这个类。
    • 此外,这个EurekaServerAutoConfiguration继承自WebMvcConfigurer,可以用来定义Spring MVC的一些配置。

    在这个类中,我们并没有发现与启动Eureka相关的代码,那么我们来看看它引入的这个EurekaServerInitializerConfiguration。

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

    可以看到,这也是一个配置类,同时它实现了ServletContextAware接口,可以在Servlet容器启动后得到ServletContext容器上下文;它还实现了SmartLifecycle,这样在spring 生命周期中会调用这个类相关的方法。比如在spring初始化时,会调用它start方法。

    @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");
                        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方法中启动了一个后台线程,它会执行这一行代码。

    eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);
    

    eurekaServerBootstrap是EurekaServerInitializerConfiguration类的成员变量,对应的类是EurekaServerBootstrap。
    来看看这个类的contextInitialized方法

    public void contextInitialized(ServletContext context) {
            try {
                initEurekaEnvironment();//初始化Eureka运行环境
                initEurekaServerContext();//初始化Eureka运行上下文
                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);
            }
        }
    

    这个方法调用了initEurekaEnvironment(),初始化Eureka运行环境;调用了initEurekaServerContext(),初始化Eureka运行上下文。关于这两个方法的细节,我们在后面的文章再细说。

    至此Eureka Server就随着Spring容器的一起启起了。


    相关流程图如下:

    Eureka源码剖析(一)注解方式启动Eureka Server.png

    相关文章

      网友评论

        本文标题:源码剖析 启动Eureka Server(一)@EnableEu

        本文链接:https://www.haomeiwen.com/subject/pcwbtqtx.html