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:自动配置导入选择器,那么它到底导入了哪些组件的选择器呢?

  1. 这个类中有这样一个方法
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;
}

2. 这个方法又调用了SpringFactoriesLoader类的静态方法:

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {String factoryTypeName = factoryType.getName();return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

3. 继续点击查看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);}
}

4. 发现一个多次出现的文件:spring.factories,全局搜索它

spring.factories

我们根据源头打开spring.factories,看到很多自动配置的文件;这就是自动配置根源的所在!

WebMvcAutoConfiguration为例,打开:

可以看到一个个都是JavaConfig配置类,并且都注入了一些bean。

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件,并将对应的 org.springframework.boot.autoconfigure包下的配置项,通过反射实例化为对应标注了@Configuration的JavaConfig形式的IOC容器配置类,然后将这些汇总成为一个实例并加载到IOC容器。

结论

  1. SpringBoot在启动的时候从类路径META-INF/spring.factories中获取EnableAutoConfiguration指定的值;
  2. 将这些值作为自动配置类导入容器,自动配置类就生效,帮我们自动配置工作;
  3. 整个J2EE的整体解决方案和自动配置都在spring-autoconfigure的jar包中;
  4. 它会给容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好;
  5. 有了自动配置类,免去了我们手动编写配置注入功能组件等工作。

spring boot原理_SpringBoot-02-原理初探之主启动类相关推荐

  1. java+caching+system_浅谈Spring boot cache使用和原理

    缓存要解决的问题:一个程序的瓶颈在于数据库,我们也知道内存的速度是大大快于硬盘的速度的.当我们需要重复地获取相同的数据的时候,我们一次又一次的请求数据库或者远程服务,导致大量的时间耗费在数据库查询或者 ...

  2. Spring Boot的自动化配置原理

    转载自 Spring Boot的自动化配置原理 随着Ruby.Groovy等动态语言的流行,相比较之下Java的开发显得格外笨重.繁多的配置.低下的开发效率.复杂的部署流程以及第三方技术集成难度大等问 ...

  3. Spring Boot的自动装配原理

    Spring Boot的"开箱即用"的原则,使得企业应用开发中各种场景的Spring开发更加快速,更加高效,由于配置大量减少,开发效率相得益彰. 启动原理:SpringBoot项目 ...

  4. Spring Boot注解的运行原理

    Spring Boot 是一个基于 Spring Framework 的开源框架,通过简化配置和开发过程,使 Spring 应用程序的开发变得更加快速和便捷.在 Spring Boot 中,注解是非常 ...

  5. Vue + Spring Boot 学习笔记02:引入数据库实现用户登录功能

    Vue + Spring Boot 学习笔记02:引入数据库实现用户登录功能 在学习笔记01里,我们利用跨域打通了前端的Vue与后端的Spring Boot,实现了用户登录功能,但是后台的登录控制器在 ...

  6. Spring Boot - 自动配置实现原理

    文章目录 Pre @SpringBootApplication 注解 @ComponentScan 注解 @SpringBootConfiguration 注解 @EnableAutoConfigur ...

  7. Spring Boot—SpringMVC自动配置原理以及扩展和全面接管SpringMVC

    文章目录 1.以下是SpringBoot对SpringMVC的默认配置 2.扩展SpringMVC 3.全面接管SpringMVC: 5.如何修改SpringBoot的默认配置 Spring MVC ...

  8. Spring Boot 静态资源访问原理解析

    一.前言 springboot配置静态资源方式是多种多样,接下来我会介绍其中几种方式,并解析一下其中的原理. 二.使用properties属性进行配置 应该说 spring.mvc.static-pa ...

  9. Spring Boot中自动配置原理以及日志的基本使用

    目录 自动配置原理 日志的基本使用 自动配置原理 自动配置原理: 1. Spring Boot启动时加载主配置类,开启了知道配置功能@EnableAutoConfiguration. 2. @Enab ...

最新文章

  1. loadrunner中的c函数----从参数列表中取参数并与特定字符进行字符串比较。
  2. 這個日本味超濃的建築竟然是台灣的小學
  3. rhel 5 检测软件awstats,cacti,ntop搭建
  4. oracle数据泵导入提示00972,oracle数据库使用expdp指定FLASHBACK_TIME遇到ORA-39150错误 | 信春哥,系统稳,闭眼上线不回滚!...
  5. 效率最高的Excel数据导入续---SSIS Package包制作图解全过程
  6. 探索停车黑科技,知位停车破局停车难题!
  7. php 中文 decode_php json_decode 解析中文
  8. 关于MySQL buffer pool的预读机制
  9. Servlet具体解释
  10. mysql找出最大的天数_mysql 计算连续登录最大天数
  11. 获取指定月份最后一天_Excel如何计算某个月的第1天和最后1天?
  12. 微星GE60有线网卡Qualcomm Atheros Bigfoot Killer E2200 ethernet card在ubuntu下无法找到驱动的解决办法...
  13. 焊缝标注vlx实用程序_【CAD自动标注插件下载】CAD自动标注插件yjbz.VLX v1.0 最新版-开心电玩...
  14. vue移动端音乐app-笔记
  15. Tomcat 服务器配置实现 IP访问限制
  16. 初探强化学习(14)DQN类算法的值高估问题的笔记
  17. python中repeat_Python Pandas Series.repeat()用法及代码示例
  18. gazebo仿真rotors调整实时比例的方法
  19. 欺骗的艺术——第二部分(1)
  20. 五色石FCS周报 2019.5.13-2019.5.19

热门文章

  1. 安装双系统(win10+Ubuntu18.0)使用一段时间后,就直接进入win10,bios启动项里也没有Ubuntu
  2. 一文解决new/delete与malloc/free相关问题:区别?注意事项?使用方式?
  3. [云炬创业管理笔记]第二章测试2
  4. 云炬Android开发笔记 5-1,2网络框架接口创建
  5. linux格式化该新添加的分区,Linux下添加新硬盘及分区格式化要点
  6. WCF中的web.config配置文件
  7. 子div在父div中置底
  8. BugkuCTF-Misc:telnet
  9. 「 每日一练,快乐水题 」258. 各位相加
  10. JVM_02 类加载器子系统