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

简介: 主要注解EnableEurekaServer的详细分析

欢迎访问我的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
@EnableEurekaServer
public 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
 */
@Configuration
public 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的启动逻辑:
@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);
}
  • EurekaServerInitializerConfiguration这个类出现在EurekaServerAutoConfiguration的注解中,通过@Import注解被实例化,由于实现了Lifecycle接口,因此会被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");

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

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关文章
|
1月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
410 128
|
1月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
324 0
|
1月前
|
Java 测试技术 API
将 Spring 的 @Embedded 和 @Embeddable 注解与 JPA 结合使用的指南
Spring的@Embedded和@Embeddable注解简化了JPA中复杂对象的管理,允许将对象直接嵌入实体,减少冗余表与连接操作,提升数据库设计效率。本文详解其用法、优势及适用场景。
243 126
|
2月前
|
XML JSON Java
Spring框架中常见注解的使用规则与最佳实践
本文介绍了Spring框架中常见注解的使用规则与最佳实践,重点对比了URL参数与表单参数的区别,并详细说明了@RequestParam、@PathVariable、@RequestBody等注解的应用场景。同时通过表格和案例分析,帮助开发者正确选择参数绑定方式,避免常见误区,提升代码的可读性与安全性。
|
16天前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
161 2
|
1月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
206 12
|
1月前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
177 1
使用Spring的@Retryable注解进行自动重试
|
1月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
118 0
探索Spring Boot的@Conditional注解的上下文配置
|
1月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
Spring中最大化@Lazy注解,实现资源高效利用