什么是 Spring Boot?
简单来说,spring boot 底层就是:spring + spring mvc + tomcat + 其他框架 starter;
spring boot 依靠 spring 的核心功能,减少了项目开发中繁杂的依赖管理和配置文件管理;
将整合其他框架所需的样板代码及配置文件提前准备好,想要使用哪个框架,直接在依赖中引入该框架的 starter 就行了;
(1)依赖管理:spring boot 将市面上常用的开源框架和中间件的依赖都整合成了 starter 依赖,想要整合哪个开源框架,直接在 pom 文件中引入该框架的 starter 依赖即可;
(2)配置文件管理:spring boot 使用 .properties、.yml 配置文件为所有引入的框架或中间件提供配置项的管理;
Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
@SpringBootApplication,Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
@SpringBootConfiguration:其实底层就是一个@Configuration 注解,就是标注该启动类是 spring ioc 容器中的一个配置类;
@EnableAutoConfiguration:该注解的作用是使用@Import 注解引入了两个类,AutoConfigurationImportSelector 和 AutoConfigurationPackages.Registrar;
该注解的作用是,打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class });
@ComponentScan:包扫描注解;
AutoConfigurationPackages.Registrar 的作用:告诉 spring boot,基包是哪一个;
该类的源码:
AutoConfigurationImportSelector 的作用:加载 spring boot 自己写的配置类;
该类实现的接口:AutoConfigurationImportSelector -> DeferredImportSelector -> ImportSelector
首先说明 ImportSelector 接口的作用;
可以简单理解为,这个接口和 @Import + @Configuration 两个注解搭配使用的;
_ImportSelector 接口有一个方法_String[] selectImports(AnnotationMetadata importingClassMetadata);
这个方法的作用是,如果你定义了一个接口 InterfaceA,又写了两个实现类 ClassB、ClassC;
如果 ClassB、ClassC 上没加 @Component 等 spring 注解,你又想要把这个类加入到 spring ioc 容器中;
可以使用这个接口方法实现;(具体的代码示例就不写了…)
回到 spring boot 中来,让我们看看 AutoConfigurationImportSelector 类使用 selectImports 方法将哪些类加入到了 ioc 容器中;
源码中最主要的一句代码:
这个就是在加载 spring.factories 文件中带有 @EnableAutoConfiguration 注解所有配置的值,也就是下面的东西:
这么多都是些啥?
这些就是 spring boot 全场景下的配置类;
为什么 spring boot 只需要引入 spring-boot-starter-web 就可以使用 spring mvc + tomcat 的功能了,完全不需要写任何配置文件,或是创建 DispatcherServlet 对象;
为什么我们只需要在 yml 配置文件中添加数据库连接信息,就可以直接连接数据库了,也没有写过 Class.forName(“com.mysql.jdbc.Driver”) 相关的代码;
就是因为 spring boot 已经将市面上大部分的开源框架或中间件的全场景配置都配置好了,并将配置类的路径名写到了 spring.factories 这个文件中;
当 spring boot 启动的时候就会加载这个文件,并将程序员想要添加的配置类加载到了 ioc 容器中;
Spring Boot 自动配置原理是什么?
注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心;
@EnableAutoConfiguration 给容器导入 META-INF/spring.factories 里定义的自动配置类,筛选有效的自动配置类;
每一个自动配置类结合对应的 xxxProperties.java 读取配置文件进行自动配置功能;
Spring Boot 启动流程
既然是 Spring Boot 的启动流程,那么入口必然是启动类中的 run 方法:
1、启动 spring boot 启动类中的 main 方法;
2、使用启动类的 class 对象,创建一个 SpringApplication 对象;
在这个类的构造函数中,会执行 _getSpringFactoriesInstances 这个方法,从 META-INF/spring.factories 文件中加载_ContextInitializer 初始化器和 Listener 监听器;
将加载到的类信息放入缓存中,等着 ioc 容器启动的时候加载使用;
3、然后执行 SpringApplication 对象的 run 方法;
该方法中会执行两个很重要的方法,prepareContext 和 refreshContext 方法;
prepareContext 将启动类的 beanDefinition 注册到 register 当中,方便后续解析;
refreshContext 就是调用执行 spring ioc 容器的刷新方法;
4、开始执行 ioc 容器的 refresh 方法;
其中会执行 invokeBeanFactoryPostProcessor 方法,这里面会执行一个 ConfigurationClassPostProcessor 配置类解析的后置处理器;
ConfigurationClassPostProcessor 实现了两个接口,BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor;
ConfigurationClassPostProcessor 会解析启动类上的注解,并执行由 @Import 注解注入的 AutoConfigurationImportSelector 类的 process 方法;
5、process 的方法中,会加载 spring.factories 文件中标注了 @EnableAutoConfiguration 注解的自动装配配置类;
这些配置类中会用 @Condition 条件注解,在 ioc 容器或引入的 jar 包中或配置文件中比对条件,来决定是否加载对应的 bean;
6、process 方法执行完毕后,剩下的就是 spring ioc 容器的启动流程;
7、在 onrefresh() 方法中会执行 createWebServer() 方法,创建 Web 容器,也就是启动 tomcat;
8、tomcat 启动后执行 Servlet 的生命周期,也就是执行 DispatcherServlet 的 initStrategies 初始化方法;
在 initStrategies 方法中会从 spring ioc 容器中初始化 spring mvc 运行所需的九大组件;
handlerMapping 控制器;handlerAdapter 适配器;handlerExceptionResolver 异常解析器;viewResolver 视图解析器;
9、执行后续的 spring ioc 容器的启动流程
Original: https://www.cnblogs.com/whatzyt/p/16096628.html
Author: whatzyt
Title: spring boot 常见问题
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/571726/
转载文章受原作者版权保护。转载请注明原作者出处!