pom.xml
父工程
- pom < spring-boot-starter-parent < spring-boot-dependencies
- 核心依赖在父工程 spring-boot-dependencies 中
启动器
- spring boot 的启动场景
- spring boot 会将所有的功能场景都变成一个个的启动器
- 需要使用什么功能,添加对应的启动器即可
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter</artifactid>
</dependency>
如 spring-boot-starter-web 会帮我们自动导入 web 环境所有需要的依赖
主程序
@springbootapplication //标注这个类是一个springboot的应用
public class springboot01application {
//将springboot应用启动
public static void main(string[] args) {
springapplication.run(springboot01application.class, args);
}
}
注解

- springboot 在启动时,从类路径下 meta-inf/spring.factories 获取指定的值
- 将这些自动配置的类导入容器,自动配置就会生效,帮我们自动配置
- 整合 javase,解决方案和自动配置的东西都在 spring-boot-autoconfigure-2.6.3.jar 这个包下
- 会将所有需要导入的组件以类名的方式返回,这些组件会被添加到容器中
| 注解名称 | 注解作用 |
|---|---|
| @springbootapplication | 标记为 springboot 的应用 |
| @springbootconfiguration | 标记为 springboot 的配置 |
| @enableautoconfiguration | 启用自动配置 |
| @componentscan | 扫描当前主启动类同级的包 |
| @configuration | 标记为 spring 配置类 |
| @component | 标记为 spring 的组件 |
| @autoconfigurationpackage | 自动配置包 |
| @import({registrar.class}) | 注册表 |
| @import({autoconfigurationimportselector.class}) | 自动导入选择器 |
autoconfigurationimportselector 类
getautoconfigurationentry() 方法
获得自动配置的入口
获取所有的配置
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;
}
getspringfactoriesloaderfactoryclass() 方法
- 标记了 enableautoconfiguration 注解的类
protected class<?> getspringfactoriesloaderfactoryclass() {
return enableautoconfiguration.class;
}
springfactoriesloader 类
loadfactorynames() 方法
- 获取所有加载配置名
public static list<string> loadfactorynames(class<?> factorytype, @nullable classloader classloader) {
classloader classloadertouse = classloader;
if (classloader == null) {
classloadertouse = springfactoriesloader.class.getclassloader();
}
string factorytypename = factorytype.getname();
return (list)loadspringfactories(classloadertouse).getordefault(factorytypename, collections.emptylist());
}
loadspringfactories() 方法
- 获取所有的配置
- 从 meta-inf/spring.factories 中读取配置文件,封装成 properties,遍历 properties 供我们使用
private static map<string, list<string>> loadspringfactories(classloader classloader) {
map<string, list<string>> result = (map)cache.get(classloader);
if (result != null) {
return result;
} else {
hashmap result = new hashmap();
try {
enumeration urls = classloader.getresources("meta-inf/spring.factories");
while(urls.hasmoreelements()) {
url url = (url)urls.nextelement();
urlresource resource = new urlresource(url);
properties properties = propertiesloaderutils.loadproperties(resource);
iterator var6 = properties.entryset().iterator();
while(var6.hasnext()) {
entry<?, ?> entry = (entry)var6.next();
string factorytypename = ((string)entry.getkey()).trim();
string[] factoryimplementationnames = stringutils.commadelimitedlisttostringarray((string)entry.getvalue());
string[] var10 = factoryimplementationnames;
int var11 = factoryimplementationnames.length;
for(int var12 = 0; var12 < var11; ++var12) {
string factoryimplementationname = var10[var12];
((list)result.computeifabsent(factorytypename, (key) -> {
return new arraylist();
})).add(factoryimplementationname.trim());
}
}
}
result.replaceall((factorytype, implementations) -> {
return (list)implementations.stream().distinct().collect(collectors.collectingandthen(collectors.tolist(), collections::unmodifiablelist));
});
cache.put(classloader, result);
return result;
} catch (ioexception var14) {
throw new illegalargumentexception("unable to load factories from location [meta-inf/spring.factories]", var14);
}
}
}
meta-inf/spring.factories
- 自动配置的核心文件
- 所有的自动配置类都在该文件中

主启动类
@springbootapplication
public class springboot01application {
//将springboot应用启动,该方法返回一个configurableapplicationcontext对象
//参数一:应用入口的类,参数二:命令行参数
public static void main(string[] args) {
springapplication.run(springboot01application.class, args);
}
}
springapplication 类的实例化
这个类主要做一下四件事
- 推断应用的类型是普通的项目还是 web 项目
- 查找并加载所有可用初始化器,设置到 initializers 属性中
- 找出所有的应用程序监听器,设置到 linsteners 属性中
- 推断并设置 main 方法的定义类,找到运行的主类
run 方法的执行
- 准备spring的上下文
- 完成容器的初始化,创建,加载等
- 在不同的时机触发监听器的不同事件
springapplication.run 做了什么?
springapplication.run 一共做了两件事,
一件是创建 springapplication 对象,在该对象初始化时,找到配置的事件监听器,并保存起来。
第二件事就是运行 run 方法,此时会将刚才保存的事件监听器根据当前时机触发不同的事件,比如容器初始化,容器创建完成等。同时也会刷新 ioc 容器,进行组件的扫描、创建、加载等工作
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论