码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • SpringBoot流程解析(一)


    目录

    注解

    SpringApplication::SpringApplication

    壹

    贰

    叁

    肆

    伍

    陆


    好久没看SpringBoot了,复习一下,温故而知新。

    1. @SpringBootApplication
    2. public class SecurityApplication {
    3. public static void main(String[] args) {
    4. SpringApplication.run(SecurityApplication.class,args);
    5. }
    6. }

    注解

    大白话教会你@SpringBootApplication中如何进行自动配置_明天一定.的博客-CSDN博客_springbootapplication自动配置一文帮你理解springBoot自动配置原理,快点卷起来https://blog.csdn.net/wai_58934/article/details/122049950?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166157703016782390538284%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166157703016782390538284&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-122049950-null-null.nonecase&utm_term=springboot&spm=1018.2226.3001.4450简单来说的作用:

    • 声明是一个spring应用程序配置类
    • 把这个类加载到ioc容器中去,完成包扫描
    • 导入配置类
    • 根据定义的扫描路径,把符合扫描规则的类装配到spring容器中

    SpringApplication::SpringApplication

    除了注解,就只有一行代码

    SpringApplication.run(SecurityApplication.class,args);

     我们来分析run方法,点进去看到

    1. public static ConfigurableApplicationContext run(Class[] primarySources, String[] args) {
    2. return (new SpringApplication(primarySources)).run(args);
    3. }

    我们先分析

    (new SpringApplication(primarySources))
    
    1. public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
    2. // 壹
    3. this.resourceLoader = resourceLoader;
    4. Assert.notNull(primarySources, "PrimarySources must not be null");
    5. // 贰
    6. this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    7. // 叁
    8. this.webApplicationType = WebApplicationType.deduceFromClasspath();
    9. // 肆
    10. setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    11. // 伍
    12. setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    13. // 陆
    14. this.mainApplicationClass = deduceMainApplicationClass();
    15. }

    壹

    配置resourceLoader

    贰

    配置主启动类

    叁

    判断当前应用程序的类型。

    1. static WebApplicationType deduceFromClasspath() {
    2. if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
    3. && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
    4. return WebApplicationType.REACTIVE;
    5. }
    6. for (String className : SERVLET_INDICATOR_CLASSES) {
    7. if (!ClassUtils.isPresent(className, null)) {
    8. return WebApplicationType.NONE;
    9. }
    10. }
    11. return WebApplicationType.SERVLET;
    12. }

    根据Class是否存在而去判断应用程序类型(反射)。

    肆

    获取初始化器的实例对象

    (Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)
    

    往代码里边点,走到

    loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    

     第一步:我们来看loadSpringFactories(classLoader)

     主要从META-INF/spring.factories中获取需要加载的类(去重),并且最后放入缓存中

    1. private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
    2. MultiValueMap result = cache.get(classLoader);
    3. if (result != null) {
    4. return result;
    5. }
    6. try {
    7. Enumeration urls = (classLoader != null ?
    8. classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
    9. ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
    10. result = new LinkedMultiValueMap<>();
    11. while (urls.hasMoreElements()) {
    12. URL url = urls.nextElement();
    13. UrlResource resource = new UrlResource(url);
    14. Properties properties = PropertiesLoaderUtils.loadProperties(resource);
    15. for (Map.Entry entry : properties.entrySet()) {
    16. String factoryTypeName = ((String) entry.getKey()).trim();
    17. for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
    18. result.add(factoryTypeName, factoryImplementationName.trim());
    19. }
    20. }
    21. }
    22. cache.put(classLoader, result);
    23. return result;
    24. }
    25. catch (IOException ex) {
    26. throw new IllegalArgumentException("Unable to load factories from location [" +
    27. FACTORIES_RESOURCE_LOCATION + "]", ex);
    28. }
    29. }

     第二步我们来看getOrDefault(factoryTypeName, Collections.emptyList()):

    从map中取出来key为ApplicationContextInitializer的value。

    伍

    获取监听器的实例对象

    分析过程同上

    陆

    找到当前应用程序的主类,开始执行

  • 相关阅读:
    Java私活200元,完成JavaSwing学生成绩管理系统(三)
    CSS 创建
    浅析Linux进程间通信方式之磁盘映射(mmap)
    从0开始设计JVM ,忘记名词跟上思路一次搞懂
    Linux - Shell、Console和Terminal的区别
    Android逆向基础——Dalvik 指令集
    Java 中 List 删除元素
    深入理解springboot的自动配置「源码分析/图文详解」
    iOS高级理论:常用的架构模式
    关于 Hypervisor的理解
  • 原文地址:https://blog.csdn.net/wai_58934/article/details/126557165
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号