1.SpringBoot项目一定会依赖spring-boot-starter-parent这个父工程
2.SpringBoot项目初始化时,如果如图添加了Web依赖,则在pom.xml文件中将会添加spring-boot-starter-web依赖
3.spring-boot-starter-web这个依赖中包含了一系列web模块开发需要的依赖包以及默认嵌入tomcat
spring-boot-dependencies的内容实际上就是SpringBoot的核心依赖以及版本,因此我们在使用SpringBoot时,再导入依赖是可以不写版本,因为在这里已经配置好了版本
实际上这个可以抽象理解成SpringBoot的启动场景,如果是普通的项目,启动器就是spring-boot-starter,Web项目就是spring-boot-starter-web等等
spring-boot-starter-web这个启动器(依赖包)实际上里面包含了web项目所需要的一系列的依赖包以及一个内嵌的默认为tomcat的服务器
一个SpringBoot项目中的依赖分为两部分,第一部分为父工程(spring-boot-starter-parent),这里记录了SpringBoot项目中所有可能出现的包的版本,对所有包的版本进行了统一的管理(主要作用),其次还有一些SpringBoot的核心依赖、配置文件的资源过滤、Maven插件。第二部分为启动器依赖,可以理解成一个具体的启动场景,比如spring-boot-starter-web这个启动器就是用于启动一个web项目,里面包含了web项目所需要的一系列的依赖包(包括一个内嵌的tomcat)。
在使用SpringBoot之后,极大地简化了我们对依赖包的导入以及版本选择(SpringBoot帮你统一管理版本,同时你只需要导入一个启动器替代以前导入一连串的相关依赖包)
@SpringBootApplication注解相当于@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan的复合,下面来解释一下这三个注解的作用
SpringBoot的配置类,继承自@Configuration,表明当前类是一个配置类,用于加载一些配置信息(实际上是为了加载自动配置导入的配置类)
这个注解相当于xml配置中的<context:component-scan />标签,由于@ComponentScan注解中没有指定basePackages,因此将会默认扫描当前配置类所在包下的所有类,比如下图会将mapper、service、controller这三个包内的组件进行扫描。
@EnableAutoConfiguration===开启自动配置功能,实际上做了两件事,第一件事就是将这个类所在的包作为自动配置类的包进行管理,第二件事就是加载一系列的自动配置类
这里有所有SpringBoot自动配置的配置类中可以进行改变的配置(自动配置的可变配置属性)
@Import注解用于将AutoConfigurationImportSelector.class这个类导入到IOC容器中
而AutoConfigurationImportSelector.class会帮助SpringBoot应用将所有符合条件(依赖包存在)的配置类都加载到当前SpringBoot创建并使用的IoC容器中。
这里是所有的配置类
配置类加载流程:AutoConfigurationImportSelector类从spring.factories加载xxxAutoConfiguration配置类,xxxAutoConfiguration会再次加载xxxxProperties配置类,这两个配置类性质不同,前者是主要的配置类,里面的配置信息是不变的(相当于spring中的xml配置文件,比如mybatis.xml),而第二个配置类的配置信息是可变的(比如jdbc.properties),第二种配置类会通过@ConfigurationProperties与SpringBoot里的全局配置文件(application.yaml/properties)关联,当SpringBoot的全局配置文件中存在配置时,将会使用SpringBoot的全局配置文件的内容(自定义内容),反之将会使用默认的配置
但并不是所有的配置文件都加载,比如注解@ConditionalOnClass(Advice.class),如果没有导入AOP的包,则Advice.class将无法找到,就不会进行相对应的配置加载
这里以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
// 表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件
@Configuration
// 启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpProperties绑定起来;并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties(HttpProperties.class)
// Spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效;判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
// 判断当前项目有没有这个类CharacterEncodingFilter,如果没有这个类则配置不生效;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass(CharacterEncodingFilter.class)
// 判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
// 即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
// 他已经和SpringBoot的配置文件(application.yaml)映射了
private final HttpProperties.Encoding properties;
// 只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
@Bean// 给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean // 判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
根据当前不同的条件判断,决定这个配置类是否生效(@Conditional注解)
一但这个配置类生效;这个配置类就会给容器中添加各种组件(@EnableConfigurationProperties注解);这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件(application.yaml)绑定的;
所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;配置文件能配置什么就可以参照某个功能对应的这个属性类
// 从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {
@AutoConfigurationPackage注解将AutoConfigurationPackages.Registrar.class类加载到IOC容器中,而这个类的主要作用就是将@AutoConfigurationPackage注解标注的类所在的package作为自动配置的package进行管理
SpringApplication.run(xxxx.class, args)
由SpringApplication.run的返回值一步一步点进去最后会进入下面那个函数
1、推断应用的类型是普通的项目还是Web项目
2、查找并加载所有可用初始化器 , 设置到initializers属性中
3、找出所有的应用程序监听器,设置到listeners属性中
4、推断并设置main方法的定义类,找到运行的主类
原文:https://www.cnblogs.com/whether/p/14166490.html