聊聊分布式架构08——SpringBoot开启微服务时代

目录

微服务架构时代

快速入门

入门详解

SpringBoot的自动配置

石器时代:XML配置bean

青铜时代:SpringConfig

铁器时代:AutoConfigurationImportSelector

手写简单Starter

SpringApplication启动原理


微服务架构时代

Spring Boot的出现与微服务架构有关,它是Spring Framework的一部分,旨在简化开发独立的、可执行的Java应用程序。Spring Boot解决了传统Java应用程序开发中的繁琐配置问题,使开发人员能够更快速地构建微服务和独立应用程序。

快速入门

如果要快速入门,这个传送门一定很有帮助------->Spring | Quickstart

入门详解

Spring入门详解的部分诸君可以看一下这篇文章:

SpringBoot入门详解-CSDN博客

SpringBoot的自动配置
石器时代:XML配置bean
XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <!-- 声明一个名为 myBean 的 Bean -->
    <bean id="myBean" class="com.elaine.MyBean">
        <property name="name" value="elaine"/>
    </bean>
​
</beans>
青铜时代:SpringConfig
java 复制代码
@Configuration
public class MyConfiguration {
​
    @Bean
    public MyBean myBean() {
        MyBean bean = new MyBean();
        bean.setName("Elaine");
        return bean;
    }
}
铁器时代:AutoConfigurationImportSelector

SpringBoot开启自动配置的注解是@EnableAutoConfiguration,但是自动配置的核心功能是通过AutoConfigurationImportSelector实现的。

java 复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
​
    Class<?>[] exclude() default {};
​
    String[] excludeName() default {};
}
  • AutoConfigurationImportSelector实现ImportSelector接口,收集需要导入的配置类,配合@Import将相应的类导入到Spring容器中。

  • 获取注⼊类的⽅法是 selectImports(),它实际调⽤的是 getAutoConfigurationEntry ,这个⽅法是获取⾃动装配类的关键,主要流程可以分为这么⼏步:

    1. 获取注解的属性,用于后面的排除

    2. 获取所有需要⾃动装配的配置类的路径:这⼀步是最关键的,从 META-INF/spring.factories 获取⾃动 配置类的路径

    3. 去掉重复的配置类和需要排除的重复类,把需要⾃动加载的配置类的路径存储起来

java 复制代码
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }
​
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            // 1.获取注解的属性
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            // 2.获取需要⾃动装配的所有配置类,读取META-INF/spring.factories,获取⾃动配置类路径
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            // 3.1.移除重复的配置
            configurations = this.removeDuplicates(configurations);
            // 3.2.处理需要排除的配置
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationEntry(configurations, exclusions);
        }
    }
手写简单Starter

在了解自动配置的原理后,就简单地创建一个自定义的spring-boot-starter吧。

文件目录贴一下:

  1. 创建自动配置类和需要定义的bean。

    java 复制代码
    @Configuration
    public class MyUserAutoConfiguration {
        @Bean
        public UserManager userManager(){
            return new UserManager();
        }
    }
    public class UserManager {
        public String sayHello() {
            return "own-starter:hello.";
        }
    }
  2. src/main/resources/META-INF/ 目录下创建一个 spring.factories 文件

    java 复制代码
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.lloyd.user.MyUserAutoConfiguration
  3. 创建一个spring-web的SpringBoot项目,添加自定义Starter的依赖。

    java 复制代码
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- 自定义starter的坐标 -->
            <dependency>
                <groupId>com.lloyd</groupId>
                <artifactId>springboot_06_own_starter</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
  4. 创建一个Rest接口进行验证

    java 复制代码
    @RestController
    public class UserController {
        @Autowired
        private UserManager userManager;
    ​
        @GetMapping("/user")
        public String sayHello(){
            return userManager.sayHello();
        }
    }

    浏览器结果:

SpringApplication启动原理

SpringApplication 这个类主要做了以下四件事情:

  1. 推断应⽤的类型是普通的项⽬还是 Web 项⽬

  2. 查找并加载所有可⽤初始化器 , 设置到 initializers 属性中

  3. 找出所有的应⽤程序监听器,设置到 listeners 属性中

  4. 推断并设置 main ⽅法的定义类,找到运⾏的主类

大致流程如下(图片来自于网络):

相关推荐
lang201509281 小时前
Spring Boot配置属性:类型安全的最佳实践
spring boot
国科安芯2 小时前
抗辐照MCU芯片在低轨商业卫星原子钟中的适配与优化
单片机·嵌入式硬件·fpga开发·架构·risc-v
koping_wu6 小时前
【RabbitMQ】架构原理、消息丢失、重复消费、顺序消费、事务消息
分布式·架构·rabbitmq
Jabes.yang7 小时前
Java面试场景:从Spring Web到Kafka的音视频应用挑战
大数据·spring boot·kafka·spring security·java面试·spring webflux
喵桑..7 小时前
kafka源码阅读
分布式·kafka
酷ku的森9 小时前
RabbitMQ的概述
分布式·rabbitmq
程序员小凯9 小时前
Spring Boot性能优化详解
spring boot·后端·性能优化
tuine10 小时前
SpringBoot使用LocalDate接收参数解析问题
java·spring boot·后端
奇树谦11 小时前
Chrominum的技术架构
架构
番茄Salad11 小时前
Spring Boot项目中Maven引入依赖常见报错问题解决
spring boot·后端·maven