• spring boot原理分析


    1、分析spring-boot-starter-parent

     <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
    他的父项目
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.0.6.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
    </parent>
    他来真正管理Spring Boot应用里面的所有依赖版本;

    按照Ctrl点击pom.xml中的spring-boot-starter-dependencies,跳转到了spring-boot-starter-dependenciespom.xmlxml配置如下(只摘抄了部分重点配置):

    从上面的spring-boot-starter-dependenciespom.xml中可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)

    2、分析spring-boot-starter-web启动器

      <dependency>
          <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

    spring-boot-starter-web:
            spring-boot-starter:spring-boot场景启动器;帮我们导入了web模块正常运行所依赖的组件;
            Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter
           相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器

    3、主程序类,主入口类

    /**
     * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
     */
    @SpringBootApplication
    public class HellStartMain {
        public static void main(String[] args) {
            //spring启动起来
            SpringApplication.run(HellStartMain.class);
        }
    }

    1、@SpringBootApplication

          Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot
    就应该运行这个类的main方法来启动SpringBoot应用;

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
            @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
            @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication

    2、@SpringBootConfiguration

       SpringBoot的配置类,标注这个类,表明SpringBoot是一个配置类

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration
    public @interface SpringBootConfiguration{
    @Configuration:配置类上面标注这个注解
    配置类---配置文件;配置也是一个组件;@Component

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Configuration {

    3、@EnableAutoConfiguration

     开启自动配置功能;以前需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    AutoConfigurationPackage:自动导入包
    @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage {

    Spring的底层注解@Import,给容器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class;
    将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
    @Import(AutoConfigurationImportSelector.class)给容器导入组件
    public class AutoConfigurationImportSelector{
       public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return StringUtils.toStringArray(configurations);
        }
    }
    }

    EnableAutoConfigurationImportSelector:导入哪些组件的选择器;
    将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
    会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,
    并配置好这些组件;有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;

    ​  SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);

    Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,

     自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们;

    其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是扫描所有jar包类路径下 META-INF/spring.factories文件中读取指定类对应的类名称列表,把扫描到的这些文件的内容包装成properties对象

    从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

     

    spring.factories 文件中有关自动配置的配置信息如下:

     

    J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-2.0.6.RELEASE.jar;

    
    
    

     

  • 相关阅读:
    第3章 Spring AOP
    第2章 Spring中的Bean
    第1章 Spring的应用
    Codeforces Round #558 (Div. 2)-Cat Party (Hard Edition)-(前缀和 + 模拟)
    Codeforces Round #552 (Div. 3)-1154E-Two Teams-(模拟+双指针)
    Codeforces Round #552 (Div. 3)-D-Walking Robot-(贪心)
    Codeforces Round #552 (Div. 3)-C-Gourmet Cat
    Codeforces Round #555 (Div. 3)
    2019年湘潭大学程序设计竞赛(重现赛)
    Buy Fruits-(构造)
  • 原文地址:https://www.cnblogs.com/cxyyh/p/10624798.html
Copyright © 2020-2023  润新知