一. @SpringBootApplication
@SpringBootApplication:
SpringBoot 应用标注在某个类上说明这个类是 SpringBoot 的主配置类, SpringBoot 就应该运行这个类的 main() 方法启动 SpringBoot 应用。
@SpringBootApplication
public class Springbootdemo2Application {
public static void main(String[] args) {
SpringApplication.run(Springbootdemo2Application.class, args);
}
}
-
查看@SpringBootApplication内部源码进行分析
1.@SpringBootConfiguration注解
@SpringBootConfiguration:
SpringBoot 的配置类,标注在某个类上,表示这是一个 SpringBoot的配置类
-
查看@SpringBootConfiguration内部源码
- 从上述源码可以看出,@SpringBootConfiguration注解内部有一个核心注解@Configuration,该注解是Spring框架提供的,表示当前类为一个配置类(XML配置文件的注解表现形式),并可以被组件扫描器扫描。由此可见,@SpringBootConfiguration注解的作用与@Configuration注解相同,都是标识一个可以被组件扫描器扫描的配置类,只不过@SpringBootConfiguration是被Spring Boot进行了重新封装命名而已
2.@EnableAutoConfiguration注解(主要)
@EnableAutoConfiguration :
开启自动配置功能,以前由我们需要配置的东西,现在由 SpringBoot帮我们自动配置,这个注解就是 Springboot 能实现自动配置的关键。
-
查看@EnableAutoConfiguration内部源码
- 从上述源码可以看出: 它是一个组合注解, Spring 中有很多以 Enable 开头的注解,其作用就是借助 @Import来收集并注册特定场景相关的 Bean ,并加载到 IOC 容器@EnableAutoConfiguration就是借助@Import来收集所有符合自动配置条件的bean定义,并加载到IoC容器
(1)@AutoConfigurationPackage注解
@AutoConfigurationPackage:自动配置包
-
查看@AutoConfigurationPackage内部源码
- 从上述源码可以看出,@AutoConfigurationPackage注解的功能是由@Import注解实现的,它是spring框架的底层注解,它的作用就是给容器中导入某个组件类,例如
@Import(AutoConfigurationPackages.Registrar.class),它就是将Registrar这个组件类导入到容器中,可查看Registrar类中registerBeanDefinitions方法,这个方法就是导入组件类的具体实现
-
查看Registrar类中registerBeanDefinitions方法
从上述源码可以看出,在Registrar类中有一个registerBeanDefinitions()方法,使用Debug模式启
动项目,可以看到选中的部分就是com.lagou。也就是说,@AutoConfigurationPackage注解的主要作
用就是将主程序类所在包及所有子包下的组件到扫描到spring容器中。
因此 在定义项目包结构时,要求定义的包结构非常规范,项目主程序启动类要定义在最外层的根目录位
置,然后在根目录位置内部建立子包和类进行业务开发,这样才能够保证定义的类能够被组件扫描器扫
描
(2)@Import({AutoConfigurationImportSelector.class})注解
将 AutoConfigurationImportSelector 这个类导入到 Spring 容器中,AutoConfigurationImportSelector 可以帮助 Springboot 应用将所有符合条件的 @Configuration配置都加载到当前 SpringBoot 创建并使用的 IOC 容器( ApplicationContext )中
-
研究AutoConfigurationImportSelector这个类
1.深入研究loadMetadata方法
- AutoConfigurationImportSelector这个类中是通过selectImports这个方法告诉springboot都需要导入那些组件
a.getAutoConfigurationEntry方法内部getCandidateConfigurations方法
-
这个方法中有一个重要方法loadFactoryNames,这个方法是让SpringFactoryLoader去加载一些组件的
a(1).继续点开loadFactory方法
名字
会去读取一个 spring.factories 的文件,读取不到会表这个错误,我们继续根据会看到,最终路径的长
这样,而这个是spring提供的一个工具类
- @EnableAutoConfiguration
就是从classpath中搜寻META-INF/spring.factories配置文件,并将其中
org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java
Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的配置类,并加载到IOC容器中
自动配置总结
- springboot应用启动;
- @SpringBootApplication起作用
- 3.@EnableAutoConfiguration
3.1@AutoConfigurationPackage:通过@Import({Registrar.class})注解将Registrar这个组件类导入到容器中,Registrar类中registerBeanDefinitions方法==>获取对应在包及所有子包下的组件到扫描到spring容器中
3.2@Import({AutoConfigurationImportSelector.class}):通过selectImports这个方法getAutoConfigurationMetadata()中的loadMetadata()方法获取所有自动配置类和条件
3.2.1 selectmports()中getAutoConfigurationEntry()中的getCandidateConfigurations()中loadFactoryNames()中的
loadSpringFactories()获取下spring.factories文件,将其中设置的配置类的全路径信息封装
3.2.2 最后通过getAutoConfigurationEntry()中的fireAutoConfigurationImportEvents()根据pom文件中加入的依赖文件筛选中最终符合当前项目运行环境对应的自动配置类
3.@ComponentScan注解
- @ComponentScan注解具体扫描的包的根路径由Spring Boot项目主程序启动类所在包位置决定,
在扫描过程中由前面介绍的@AutoConfigurationPackage注解进行解析,从而得到Spring Boot项目主
程序启动类所在包的具体位置