2、SpringBoot 自动装配源码分析

2.1 源码分析

pom.xml

spring-boot-starter-parent ===》spring-boot-dependencies

  • spring-boot-dependencies管理了 SpringBoot 的核心依赖,以及他们的版本号

    • 因此,配置相关依赖的时候,并不需要指定版本号。

启动器

  •     <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starterartifactId>
        dependency>
    
  • spring-boot-starter-web 会自动导入 web 环境所有的依赖

  • springboot 将所有的功能场景,都变为一个一个的启动器,想要哪种功能,就只需要导入相应的启动器就好。

  • 官方文档启动器地址:https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter

主程序

//程序主入口  本身既是一个Spring 的组件
//@SpringBootApplication 标注这个类是一个springboot的应用  启动类下的所有资源被导入
@SpringBootApplication
public class HelloworldApplication {

    public static void main(String[] args) {
        // 将springboot应用启动   通过反射,加载上面的类,并传递参数
        SpringApplication.run(HelloworldApplication.class, args);
    }

}
  • 注解:

  • @SpringBootApplication    
    	@SpringBootConfiguration				//springboot的配置
            @Configuration			//说明该类是一个spring的配置类
                @Component 	//说明该类是一个spring的组件
    
    
        @EnableAutoConfiguration														//开启自动装配
            @AutoConfigurationPackage												//自动配置包
    			@Import({Registrar.class})										//导入自动配置包注册器
    				metadata												//元数据
    		@Import({AutoConfigurationImportSelector.class})						//自动配置导入选择器
                        …… 见下文
        @ComponentScan									//扫描包
                        
    //接@Import({AutoConfigurationImportSelector.class})下面
    //获取所有的配置
    List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
    	//点入getCandidateConfigurations 获得候选的配置
    	……见下文
    
  • 获取候选的配置

  •     protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
            List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
            Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
            return configurations;
        }
    
    • loadFactoryNames首先加载了:

      • getBeanClassLoader()

      • getSpringFactoriesLoaderFactoryClass()
        2、SpringBoot 自动装配源码分析_第1张图片

        • @EnableAutoConfiguration包含了EnableAutoConfiguration.class
        • @SpringBootApplication 正好包含了 @EnableAutoConfiguration
        • @SpringBootApplication被注在了主程序的类(启动类)上,也就相当于**把启动类下的所有资源导入了进去**
    • 同一页面下的Assert.notEmpty

      • Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        
        //断言.非空(确保spring.factories配置文件的正确)
        
      • META-INF/spring.factories是一个自动配置的核心文件,包含了各种配置

      2、SpringBoot 自动装配源码分析_第2张图片

      2、SpringBoot 自动装配源码分析_第3张图片

      2、SpringBoot 自动装配源码分析_第4张图片

      2、SpringBoot 自动装配源码分析_第5张图片

    • 再看loadFactoryNames,点进去,看到

      • SpringFactoriesLoaderspring 工厂的加载
        2、SpringBoot 自动装配源码分析_第6张图片

      • 如上文所说的,通过@SpringBootApplication加载了启动类下的资源
        2、SpringBoot 自动装配源码分析_第7张图片

      2、SpringBoot 自动装配源码分析_第8张图片

      • 如此==得到了所有的配置类==

2.2 脑图分析

源码脑图

总结:SpringBoot 所有的自动配置都是在启动的时候扫描注册加载,spring.factories所有的自动配置都在该文件中,但是是否生效,要看是否配置了相应的springboot-starter-XXX,如果配置了,那么该启动器下所有的自动装配即会生效。

在这里插入图片描述

  1. SpringBoot 在启动的时候,从类路径spring-boot-autoconfigure-2.4.5.jar/META-INF/spring.factories下,获取指定的值。
  2. 将这些自动配置的类导入容器,自动配置就会生效(见下文)
  3. 以前需要手动配置的东西,现在springboot代理做了
  4. 整个JavaEE,解决方案和所有的自动配置都在spring-boot-autoconfigure-2.4.5.jar包下
  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器。
  6. 容器中会存在非常多的XXXautoconfigure的文件(包含大量的@Bean (配置为组件)),就是这些类给容器中导入了这个场景需要的所有组件;并自动装配(@Configuration,就是Spring中的JavaConfig)
  7. 有了自动配置类,就免去了我们手动编写配置文件的工作!

2.3 小结

以上原理都是在讲@SpringBootApplication这个注解所扮演的功能,即==自动装配的核心角色==,而SpringApplication.run(HelloworldApplication.class, args);即启动,则见下文。

你可能感兴趣的:(java,SpringBoot,spring,boot,java)