spring-boot-learning自动配置原理
启动器:
不同的场景有不同的启动器:
- @SpringBootApplication
- public class DoneApplication {
- public static void main(String[] args) {
- SpringApplication.run(DoneApplication.class, args);
- }
- }
- @SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,
SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
这个注解的详如下:
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan(
- excludeFilters = {@Filter(
- type = FilterType.CUSTOM,
- classes = {TypeExcludeFilter.class}
- ), @Filter(
- type = FilterType.CUSTOM,
- classes = {AutoConfigurationExcludeFilter.class}
- )}
- )
- public @interface SpringBootApplication {
- @SpringBootConfiguration springboot的配置类的注解,标注在某个类上,表示这是一个Spring Boot的配置类
- @EnableAutoConfiguration 开启自动配置,告诉SpringBoot开启自动配置功能,详解如下:
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- @AutoConfigurationPackage
- @Import({AutoConfigurationImportSelector.class})
- public @interface EnableAutoConfiguration {
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- @Import({Registrar.class})
- public @interface AutoConfigurationPackage {
@Import(Registrar.class):
Spring的底层注解@Import,给容器中导入一个组件;导入的组件由 Registrar.class;
将主配置类(@SpringBootApplication: 标注的类)的所在包及下面所有子包里面的所有组件扫描到容器
AutoConfigurationImportSelector 类的作用就是往 Spring 容器中导入组件,导入哪些组件的选择器
- 将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
- 会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件, 并配置好这些组件;
流程;
@SpringbootApplication注解--@EnableAutoConfiguration--@Import(AutoConfigurationImportSelector.class)重要就是这个类
AutoConfigurationImportSelector这个类有个方法:
- @Override
- public String[] selectImports(AnnotationMetadata annotationMetadata) {
- if (!isEnabled(annotationMetadata)) {
- return NO_IMPORTS;
- }
- AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
- return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
- }
AutoConfigurationImportSelector 的 selectImports 就是用来返回需要导入的组件的全类名数组的
就是通过方法getAutoConfigurationEntry方法
- getCandidateConfigurations方法里面
- SpringFactoriesLoader里面函数loadFactoryNames
loadFactoryNames里面的
- public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
- String factoryTypeName = factoryType.getName();
- return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
- }
- private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
- MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
- if (result != null) {
- return result;
- } else {
- try {
- Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
- LinkedMultiValueMap result = new LinkedMultiValueMap();
- 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[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
- int var10 = var9.length;
- for(int var11 = 0; var11 < var10; ++var11) {
- String factoryImplementationName = var9[var11];
- result.add(factoryTypeName, factoryImplementationName.trim());
- }
- }
- }
- cache.put(classLoader, result);
- return result;
- } catch (IOException var13) {
- throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
- }
- }
- }
1111获取配置文件信息:
- Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
2222通过函数loadSpringFactories获取一个map集合:
- private static Map<String, List<String>> loadSpringFactories
先寻找传入了什么
回到选择器:
333从返回的 Map 中通过刚才传入的 EnableAutoConfiguration.class
参数,获取该 key 下的所有值。
spring-boot-learning自动配置原理的更多相关文章
- Spring Boot的自动配置原理及启动流程源码分析
概述 Spring Boot 应用目前应该是 Java 中用得最多的框架了吧.其中 Spring Boot 最具特点之一就是自动配置,基于Spring Boot 的自动配置,我们可以很快集成某个模块, ...
- Spring boot 的自动配置
Xml 配置文件 日志 Spring Boot对各种日志框架都做了支持,我们可以通过配置来修改默认的日志的配置: #设置日志级别 logging.level.org.springframework=D ...
- spring boot(12)-数据源配置原理
本篇讲的不仅是数据源配置,这也是spring boot实现自动配置的一部分.要理解数据源的配置原理,首先要理解第十篇tomcat连接池的配置 数据源配置源码 这里截取org.springframewo ...
- 了解Spring Boot的自动配置
摘自:https://www.jianshu.com/p/ddb6e32e3faf Spring Boot的自动配置给开发者带来了很大的便利,当开发人员在pom文件中添加starter依赖后,mave ...
- Spring Boot的自动配置
Spring Boot的自动配置 --摘自https://www.hollischuang.com/archives/1791 随着Ruby.Groovy等动态语言的流行,相比较之下Java的开发显得 ...
- 初识Spring Boot框架(二)之DIY一个Spring Boot的自动配置
在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个Spring Boot是怎么实现自动配置的,那么今天我就带小伙伴我们自己来实现一个简单 ...
- spring boot 系列之六:深入理解spring boot的自动配置
我们知道,spring boot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子: Spring的JdbcTemplate是不是在Classpath里面?如果是,并 ...
- Spring Boot 排除自动配置的 4 种方法,关键时刻很有用!
Spring Boot 提供的自动配置非常强大,某些情况下,自动配置的功能可能不符合我们的需求,需要我们自定义配置,这个时候就需要排除/禁用 Spring Boot 某些类的自动化配置了. 比如:数据 ...
- 自定义spring boot的自动配置
文章目录 添加Maven依赖 创建自定义 Auto-Configuration 添加Class Conditions 添加 bean Conditions Property Conditions Re ...
- Spring Boot的自动配置的原理浅析
一.原理描述 Spring Boot在进行SpringApplication对象实例化时会加载META-INF/spring.factories文件,将该配置文件中的配置载入到Spring容器. 二. ...
随机推荐
- PRML 回归的线性模型
线性模型最简单的形式就是输入变量的线性模型,但是,将一组输入变量的非线性函数进行线性组合,我们可以得到一类更加有用的函数,本章我们的讨论重点就是输入变量的非线性函数的线性组合. 1 线性基 ...
- 还在争论WPS、Office哪个更好用?这款云办公工具才是真的香!
最近,金山WPS更新狠狠的刷了一波存在感.尤其是xlookup函数,着实是有被惊艳到,也让大家看到了国产办公软件的进步.甚至有人认为WPS已经超越了传统的办公软件--微软office.WPS的优点固然 ...
- StackExchange.Redis 实现SetNx
今天有同事指出如何在StackExchange.Redis 实现Redis的原生命令. ConnectionMultiplexer redis = ConnectionMultiplexer.Conn ...
- linux shell脚本批量修改密码,无需交互输入
转至:https://blog.csdn.net/weixin_34409357/article/details/89833777?utm_medium=distribute.pc_relevant. ...
- ubuntu 下的ftp安装及root身份远程配置
第一步:在 Ubuntu 中安装 VSFTPD 服务器 //安装 VSFTPD 二进制包 $ sudo apt-get update $ sudo apt-get install vsftpd //使 ...
- c语言——uthash使用
参考:https://troydhanson.github.io/uthash/userguide.html https://blog.csdn.net/lovemust/article/detail ...
- python浅拷贝与深拷贝浅析
首先我们要明确,python中大多数都是浅拷贝,我们先说原因: 1.时间花费更少 2.内存更小 3.效率更高,浅拷贝只拷贝顶层数据,一般情况下比深拷贝效率高. 容器(如列表)切片是浅拷贝
- 转发有关tomcat和nginx
nginx 与 tomcat 组合搭建web服务 部分内容转自 http://www.cnblogs.com/naaoveGIS/ 1. Web服务 nginx是常用的web服务器,用于获取静态资 ...
- linux基本篇--入门成神之路
一.linux基础操作 1.初识bash shell概念 shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口,他接受用户输入的命令并把它送入内核去执行,实际上shell是一个命令解释 ...
- nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)
问题场景 服务器重启后,重启nginx时报错nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: N ...