• 聊聊分布式架构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
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.       xsi:schemaLocation="http://www.springframework.org/schema/beans
    5.                           http://www.springframework.org/schema/beans/spring-beans.xsd">
    6.    
    7.    <bean id="myBean" class="com.elaine.MyBean">
    8.        <property name="name" value="elaine"/>
    9.    bean>
    10. beans>
    青铜时代:SpringConfig
    1. @Configuration
    2. public class MyConfiguration {
    3.    @Bean
    4.    public MyBean myBean() {
    5.        MyBean bean = new MyBean();
    6.        bean.setName("Elaine");
    7.        return bean;
    8.   }
    9. }
    铁器时代:AutoConfigurationImportSelector

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

    1. @Target({ElementType.TYPE})
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Documented
    4. @Inherited
    5. @AutoConfigurationPackage
    6. @Import({AutoConfigurationImportSelector.class})
    7. public @interface EnableAutoConfiguration {
    8.    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    9.    Class[] exclude() default {};
    10.    String[] excludeName() default {};
    11. }
    • AutoConfigurationImportSelector实现ImportSelector接口,收集需要导入的配置类,配合@Import将相应的类导入到Spring容器中。

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

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

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

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

    1. public String[] selectImports(AnnotationMetadata annotationMetadata) {
    2.        if (!this.isEnabled(annotationMetadata)) {
    3.            return NO_IMPORTS;
    4.       } else {
    5.            AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
    6.            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    7.       }
    8.   }
    9.    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    10.        if (!this.isEnabled(annotationMetadata)) {
    11.            return EMPTY_ENTRY;
    12.       } else {
    13.            // 1.获取注解的属性
    14.            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
    15.            // 2.获取需要⾃动装配的所有配置类,读取META-INF/spring.factories,获取⾃动配置类路径
    16.            List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
    17.            // 3.1.移除重复的配置
    18.            configurations = this.removeDuplicates(configurations);
    19.            // 3.2.处理需要排除的配置
    20.            Set exclusions = this.getExclusions(annotationMetadata, attributes);
    21.            this.checkExcludedClasses(configurations, exclusions);
    22.            configurations.removeAll(exclusions);
    23.            configurations = this.getConfigurationClassFilter().filter(configurations);
    24.            this.fireAutoConfigurationImportEvents(configurations, exclusions);
    25.            return new AutoConfigurationEntry(configurations, exclusions);
    26.       }
    27.   }
    手写简单Starter

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

    文件目录贴一下:

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

      1. @Configuration
      2. public class MyUserAutoConfiguration {
      3.    @Bean
      4.    public UserManager userManager(){
      5.        return new UserManager();
      6.   }
      7. }
      8. public class UserManager {
      9.    public String sayHello() {
      10.        return "own-starter:hello.";
      11.   }
      12. }
    2. src/main/resources/META-INF/ 目录下创建一个 spring.factories 文件

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

      1.        
      2.            org.springframework.boot
      3.            spring-boot-starter-web
      4.        
      5.        
      6.        
      7.            com.lloyd
      8.            springboot_06_own_starter
      9.            0.0.1-SNAPSHOT
      10.        
      11.        
      12.            org.springframework.boot
      13.            spring-boot-starter-test
      14.            test
      15.        
      16.    

    4. 创建一个Rest接口进行验证

      1. @RestController
      2. public class UserController {
      3.    @Autowired
      4.    private UserManager userManager;
      5.    @GetMapping("/user")
      6.    public String sayHello(){
      7.        return userManager.sayHello();
      8.   }
      9. }

      浏览器结果:

    SpringApplication启动原理

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

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

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

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

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

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

  • 相关阅读:
    人人都会数据分析
    Ubuntu本地快速搭建web小游戏网站,公网用户远程访问【内网穿透】
    rv1126-rv1109-驱动方法
    基于Python的接口自动化-构建mock接口服务
    外汇天眼;VT Markets 赞助玛莎拉蒂MSG Racing电动方程式世界锦标赛
    Exadata想要补装Oracle 11g的注意事项
    golang--文件的多个处理场景
    Linux部署Kafka2.8.1
    Jenkins+Docker+SVN实现SpringBoot项目半自动化部署
    贪心算法——硬币找零2——python
  • 原文地址:https://blog.csdn.net/Elaine2391/article/details/133909015