SpringBoot-02-原理初探之主启动类
2. 原理初探
2.1 pom.xml
父依赖
主要依赖一个父项目,主要管理项目的资源过滤和插件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
点进去,发现还有一个父依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
这里才是真正管理SpringBoot应用里所有依赖版本的地方,SpringBoot的版本控制中心;
以后导依赖默认不需要写版本;但是如果导入的包没有在依赖中管理就需要手动配置版本
启动器 spring-boot-starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web
:帮我们导入web模块正常运行所依赖的组件。
需要使用什么功能,就只需要找到对应的启动器即可!
2.2 主启动类
默认的主启动类
//SpringBootApplication:标注这个类是一个SpringBoot的应用
@SpringBootApplication
public class Springboot01HelloApplication {
public static void main(String[] args) {
//将SpringBoot应用启动
SpringApplication.run(Springboot01HelloApplication.class, args);
}
}
注解:
@SpringBootConfiguration:springboot的配置
@Configuration:spting配置类
@Component:说明这也是spring的组件
@EnableAutoConfiguration:自动配置
@AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class):自动配置‘包注册’
@Import(AutoConfigurationImportSelector.class):自动配置导入
//获取所有的配置
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
获取候选的配置:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
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;
}
@SpringBootApplication
作用:标注在某个类上说明这个类是SpringBoot的主配置类
,SpringBoot就运行在这个类的main方法上来启动
SpringBoot应用。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan (excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
@ComponentScan
它对应XML配置中的元素。
作用:自动扫描并加载所有符合条件的组件或bean
,将这个bean定义加载到IOC容器中。
@SpringBootConfiguration
作用:标注在类上,表示这是一个springboot的配置类
继续点进去:
@Configuration
public @interface SpringBootConfiguration {
...
}
@Component
public @interface Configuration {
...
}
这里出现的注解及解释:
@Configuration :说明这是一个配置类,配置类就是对应Spring的xml配置文件
;
@Component:说明启动类本身也是Spring中的一个组件
,负责启动应用。
@EnableAutoConfiguration
作用:开启自动配置功能
,即以前我们需要自己配置的东西,现在SpringBoot自动帮我们配置。
点进该注解:
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
这里出现的注解:
@AutoConfigurationPackage:自动配置包
Registrar.class的作用:将主启动类所在包及所有子包里的所有组件扫描到Spring容器
中。
@Import(Registrar.class)
public @interface AutoConfigurationPackage {
...
}
@import:表示给容器导入一个组件
@Import(AutoConfigurationImportSelector.class):给容器导入组件
;
AutoConfigurationImportSelector:自动配置导入选择器,那么它到底导入了哪些组件的选择器呢?
这个类中有这样一个方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
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;
}
这个方法又调用了SpringFactoriesLoader类的静态方法:
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
继续点击查看loadSpringFactories方法
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
} try {
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryTypeName = ((String) entry.getKey()).trim();
for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
发现一个多次出现的文件:
spring.factories
,全局搜索它
spring.factories
我们根据源头打开spring.factories,看到很多自动配置的文件;这就是自动配置根源的所在!
以WebMvcAutoConfiguration
为例,打开:
可以看到一个个都是JavaConfig配置类,并且都注入了一些bean。
所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories
配置文件,并将对应的 org.springframework.boot.autoconfigure
包下的配置项,通过反射实例化为对应标注了@Configuration
的JavaConfig形式的IOC容器配置类,然后将这些汇总成为一个实例并加载到IOC容器。
结论
- SpringBoot在启动的时候从类路径
META-INF/spring.factories
中获取EnableAutoConfiguration
指定的值; - 将这些值作为自动配置类导入容器,自动配置类就生效,帮我们自动配置工作;
- 整个J2EE的整体解决方案和自动配置都在
spring-autoconfigure
的jar包中; - 它会给容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好;
- 有了自动配置类,免去了我们手动编写配置注入功能组件等工作。
SpringBoot-02-原理初探之主启动类的更多相关文章
- SpringBoot无法书写主启动类的情况之一
首先需要引入 spring-boot-starter-web 依赖[springboot web 项目 启动器 jar包]: 如果使用镜像请确保镜像路径正确,可参看笔者博客园m-yb的maven 安装 ...
- SpringBoot-02 运行原理初探
SpringBoot-02 运行原理初探 本篇文章根据b站狂神编写 pom.xml 2.1.父依赖 其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件! <parent> < ...
- 狂神说SpringBoot02:运行原理初探
狂神说SpringBoot系列连载课程,通俗易懂,基于SpringBoot2.2.5版本,欢迎各位狂粉转发关注学习. 微信公众号:狂神说(首发) Bilibili:狂神说Java(视频) 未经作 ...
- 2 — springboot的原理
1.初步探索:第一个原理:依赖管理 发现:这里面存放着各种jar包 和 版本号 这也是:我们在前面第一个springboot项目创建中勾选了那个web,然后springboot就自动帮我们导入很多东西 ...
- SpringBoot 02: 初识SpringBoot
1. SpringBoot 产生原因 spring, springmvc框架使用上的一些缺点: 需要使用的大量的配置文件 还需要配置各种对象 需要把使用的对象放入到spring容器中才能使用对象 需要 ...
- SpringBoot之旅第六篇-启动原理及自定义starter
一.引言 SpringBoot的一大优势就是Starter,由于SpringBoot有很多开箱即用的Starter依赖,使得我们开发变得简单,我们不需要过多的关注框架的配置. 在日常开发中,我们也会自 ...
- SpringBoot源码学习系列之启动原理简介
本博客通过debug方式简单跟一下Springboot application启动的源码,Springboot的启动源码是比较复杂的,本博客只是简单梳理一下源码,浅析其原理 为了方便跟源码,先找个Ap ...
- SpringBoot主程序类,主入口类
主程序类,主入口类 /** * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用 */ @SpringBootApplication publi ...
- springboot系列(三) 启动类中关键注解作用解析
一.Springboot:请求入口 @SpringBootApplication @EnableAspectJAutoProxy @EnableScheduling @EnableTransactio ...
随机推荐
- 【Apollo】(2)--- Apollo架构设计
Apollo架构设计 上一篇博客有讲到:[Apollo](1)--- Apollo入门介绍篇 这篇来写Apollo的核心架构设计 一.整体架构 Apollo整体架构图,已由作者宋顺已经给出: 这幅图所 ...
- getting session bus failed: //bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.
今天在调试dbus程序的时候,运行程序出现了getting session bus failed: //bin/dbus-launch terminated abnormally with the f ...
- magento paypal测试配置
1.登录https://developer.paypal.com 2.在https://developer.paypal.com/developer/accounts/中创建
- WSGI 配置禁止反向DNS查找
原文链接:https://opendev.org/starlingx/ha/src/commit/045a37c672a92f1412629a176f51183c88882e61/service-mg ...
- Webfunny知识分享:webpack sourceMap解析源码
前端的业务越来越庞大,导致我们需要引入的js等静态资源文件的体积也越来越大,不得不使用压缩js文件的方式来提高加载的效率. 编译工具的诞生,极大地方便了我们处理js文件的这一过程,但压缩后的js文件极 ...
- 树链剖分详解&题解 P6098 【[USACO19FEB]Cow Land G】
看到各位大佬们已经把其他的东西讲的很明白了,我这个 juruo 就讲一讲最基本的树链剖分吧. 0.树剖是什么?能吃吗? 不能吃 树剖是树链剖分的简称,我们一般说的树剖其实指重链剖分.当然,还有一种长链 ...
- vue组件获取和vue-cli的基本了解
Vue获取组件的一些方法 this.$refs.xxx 给标签绑定ref属性,获取的是当前DOM对象 给组件绑定ref属性,获取的是组件实例对象 this.$parent 获取当前组件的父组件,为一个 ...
- .net 安装部署诀窍
1.解决方案资源管理器中有多个类库项目和一个启动主项目时:各类库项目的生成路径设为bin\debug: 启动主项目的生成路径设成指定的主输出路径: 2.打包时在应用程序文件夹中添加主输出即可,主输出的 ...
- Codeforces 1321C Remove Adjacent
题意 给你一个字符串,字符\(s_i\)可以被伤处当且仅当\(s_{i-1}=s_i-1\)或\(s_{i+1}=s_i-1\).问最多能删几个字符. 解题思路 其实,有个很简单的做法就是从\(z\) ...
- openresty(nginx+lua)初识
1.新增项目配置文件: vim /usr/example/example1.conf --将以下内容加入example1.conf server { listen 80; server_name _; ...