SpringBoot项目无需各种配置文件,一个main方法,就能把项目启动起来。那么我们看看SpringBoot是如何进行自动配置和启动的。

    1. SpringBoot通过main方法启动SpringApplication类的静态方法run()来启动项目。在run方法中必须要传入一个被@SpringBootApplication注解的类。SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就会运行这个类的main方法来启动SpringBoot项目。

      SpringBoot自动装配原理 - 图1

    2. 根据注释的意思,run方法从一个使用了默认配置的指定资源启动一个SpringApplication并返回ApplicationContext对象,这个默认配置如何指定呢?

      SpringBoot自动装配原理 - 图2

    3. 这个默认配置来源于@SpringBootApplication注解,这个注解是个复合注解,里面还包含了其他注解。

      SpringBoot自动装配原理 - 图3
      其中有三个注解是比较重要的:

    • @SpringBootConfiguration:这个注解的底层是一个@Configuration注解,也就是说他是一个配置类,意思被@Configuration注解修饰的类是一个IOC容器,支持JavaConfig的方式来进行配置;
    • @ComponentScan:这个就是扫描注解的意思,默认扫描当前类所在的包及其子包下包含的注解,将@Controller/@Service/@Component/@Repository等注解标注的类加载到IOC容器中;
    • @EnableAutoConfiguration:这个注解表明启动自动装配,里面包含两个比较重要的注解@AutoConfigurationPackage和@Import。

      1. ![](https://cdn.nlark.com/yuque/0/2021/png/12909202/1619058730538-9e239c9f-d5a4-4e09-a93c-907f6c39b5fa.png#clientId=ub2d73b77-5f3a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=150&id=u449e3ea1&margin=%5Bobject%20Object%5D&originHeight=200&originWidth=504&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=ufa4e49aa-c5ac-49a1-a114-acb8825594f&title=&width=378)
    • @AutoConfigurationPackage和@ComponentScan一样,也是将主配置类所在的包及其子包里面的组件扫描到IOC容器中,但是区别是@AutoConfigurationPackage扫描@Enitity、@MapperScan等第三方依赖的注解,@ComponentScan只扫描@Controller/@Service/@Component/@Repository这些常见注解。所以这两个注解扫描的对象是不一样的。

    • @Import(AutoConfigurationImportSelector.class)是自动装配的核心注解,AutoConfigurationImportSelector.class中有个selectImports方法

    image.png
    selectImports方法中调用了getCandidateConfigurations方法
    SpringBoot自动装配原理 - 图5
    getCandidateConfigurations方法中,我们可以看下断言,说找不到META-INF/spring.factories,由此可见,这个方法是用来找META-INF/spring.factories文件的
    SpringBoot自动装配原理 - 图6
    我们可以定位到这个方法所在的类处于spring-boot-autoconfigure-.jar包中,
    SpringBoot自动装配原理 - 图7
    其中spring.factories文件是一组组的key=value的形式,包含了key为EnableAutoConfiguration的全类名,value是一个AutoConfiguration类名的列表,以逗号分隔。
    SpringBoot自动装配原理 - 图8
    最终,@EnableAutoConfiguration注解通过@SpringBootApplication注解被间接地标记在了SpringBoot的启动类上,SpringApplicaton.run方法的内部就会执行selectImports方法,进而找到所有JavaConfig配置类全限类名对应的class,然后将所有自动配置类加载到IOC容器中。

    那么这些类是如何获取默认属性值的呢?以ServletWebServerFactoryAutoConfiguration为例,它是Servlet容器的自动配置类
    SpringBoot自动装配原理 - 图9
    该类上开启了@EnableConfigurationProperties(ServerProperties.class)注解,最终找到了ServerProperties类。至此,我们大致可以了解。在全局配置的属性如:server.port等,通过@ConfigurationProperties注解,绑定到对应的XxxxProperties配置实体类上封装为一个bean,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。
    SpringBoot自动装配原理 - 图10
    总结:
    image.png
    SpringBoot启动的时候通过@EnableAutoConfiguration注解找到META-INF/spring.factories文件中的所有自动配置类,并对其加载,这些自动配置类都是以AutoConfiguration结尾来命名的。它实际上就是一个JavaConfig形式的IOC容器配置类,通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,如server.port。
    Properties类的含义:封装配置文件的相关属性。
    AutoConfiguration类的含义:自动配置类,添加到IOC容器中。