濮阳建设工程网站公司单位电话号码大全

news/2025/9/30 9:40:32/文章来源:
濮阳建设工程网站,公司单位电话号码大全,网站页面优化,一级页面的网站怎么做Spring Boot 源码学习系列 初识 SpringApplication 引言往期内容主要内容1. Spring Boot 应用程序的启动2. SpringApplication 的实例化2.1 构造方法参数2.2 Web 应用类型推断2.3 加载 BootstrapRegistryInitializer2.4 加载 ApplicationContextInitializer2.5 加载 Applicatio…Spring Boot 源码学习系列 初识 SpringApplication 引言往期内容主要内容1. Spring Boot 应用程序的启动2. SpringApplication 的实例化2.1 构造方法参数2.2 Web 应用类型推断2.3 加载 BootstrapRegistryInitializer2.4 加载 ApplicationContextInitializer2.5 加载 ApplicationListener2.6 推断应用入口类 总结 引言 往期的博文Huazie 围绕 Spring Boot 的核心功能带大家从总整体上了解 Spring Boot 自动配置的原理以及自动配置核心组件的运作过程。这些内容大家需要重点关注只有了解这些基础的组件和功能我们在后续集成其他三方类库的 Starters 时才能够更加清晰地了解它们都运用了自动配置的哪些功能。 在学习上述 Spring Boot 核心功能的过程中相信大家可能都会尝试启动自己新建的 Spring Boot 的项目并 Debug 看看具体的执行过程。本篇开始就将从 Spring Boot 的启动类 SpringApplication 上入手带领大家了解 Spring Boot 启动过程中所涉及到的源码和知识点。 往期内容 在开始本篇的内容介绍之前我们先来看看往期的系列文章【有需要的朋友欢迎关注系列专栏】 Spring Boot 源码学习 Spring Boot 项目介绍 Spring Boot 核心运行原理介绍 【Spring Boot 源码学习】EnableAutoConfiguration 注解 【Spring Boot 源码学习】SpringBootApplication 注解 【Spring Boot 源码学习】走近 AutoConfigurationImportSelector 【Spring Boot 源码学习】自动装配流程源码解析上 【Spring Boot 源码学习】自动装配流程源码解析下 【Spring Boot 源码学习】深入 FilteringSpringBootCondition 【Spring Boot 源码学习】OnClassCondition 详解 【Spring Boot 源码学习】OnBeanCondition 详解 【Spring Boot 源码学习】OnWebApplicationCondition 详解 【Spring Boot 源码学习】Conditional 条件注解 【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解 【Spring Boot 源码学习】RedisAutoConfiguration 详解 【Spring Boot 源码学习】JedisConnectionConfiguration 详解 主要内容 1. Spring Boot 应用程序的启动 在 《【Spring Boot 源码学习】SpringBootApplication 注解》这篇博文中我们新建了一个基于 Spring Boot 的测试项目。 如上图中的 DemoApplication 就是我们这里 Spring Boot 项目的入口类。 同时我们可以看到 DemoApplication 的 main 方法中直接调用了 SpringApplication 的静态方法 run用于启动整个 Spring Boot 项目。 先来看看 run 方法的源码 public static ConfigurableApplicationContext run(Class? primarySource, String... args) {return run(new Class?[] { primarySource }, args); }public static ConfigurableApplicationContext run(Class?[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args); }阅读上述 run 方法我们可以看到实际上是 new 了一个SpringApplication 对象【其构造参数 primarySources 为加载的主要资源类通常就是 SpringBoot 的入口类】并调用其 run 方法【其参数 args 为传递给应用程序的参数信息】启动然后返回一个应用上下文对象 ConfigurableApplicationContext 。 通过观察这个内部的 run 方法实现我们也可以在自己的 Spring Boot 启动入口类中像如下这样去写 SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication springApplication new SpringApplication(DemoApplication.class);// 这里可以调用 SpringApplication 提供的 setXX 或 addXX 方法来定制化设置springApplication.run(args);}}2. SpringApplication 的实例化 上面已经看到我们在实例化 SpringApplication 了废话不多说直接翻看其源码【Spring Boot 2.7.9】 public SpringApplication(Class?... primarySources) {this(null, primarySources);}SuppressWarnings({ unchecked, rawtypes })public SpringApplication(ResourceLoader resourceLoader, Class?... primarySources) {this.resourceLoader resourceLoader;Assert.notNull(primarySources, PrimarySources must not be null);this.primarySources new LinkedHashSet(Arrays.asList(primarySources));// 推断web应用类型this.webApplicationType WebApplicationType.deduceFromClasspath();// 加载并初始化 BootstrapRegistryInitializer及其实现类this.bootstrapRegistryInitializers new ArrayList(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));// 加载并初始化 ApplicationContextInitializer及其实现类setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 加载并初始化ApplicationListener及其实现类setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 推断入口类this.mainApplicationClass deduceMainApplicationClass();}由上可知SpringApplication 提供了两个构造方法而其核心的逻辑都在第二个构造方法中实现。 2.1 构造方法参数 我们从上述源码可知SpringApplication 的第二个构造方法有两个参数分别是 ResourceLoader resourceLoader ResourceLoader 为资源加载的接口它用于在Spring Boot 启动时打印对应的 banner 信息默认采用的就是 DefaultResourceLoader。实操过程中如果未按照 Spring Boot 的 “约定” 将 banner 的内容放置于 classpath 下或者文件名不是 banner.* 格式默认资源加载器是无法加载到对应的 banner 信息的此时则可通过 ResourceLoader 来指定需要加载的文件路径【这个后面我们专门来实操一下敬请期待】。Class?... primarySources 该参数为可变参数默认我们会传入 Spring Boot 的入口类【即 main 方法所在的类】如上面我们的 DemoApplication 。如果作为项目的引导类该类需要满足一个条件就是被注解 EnableAutoConfiguration 或其组合注解标注。在前面的《【Spring Boot 源码学习】SpringBootApplication 注解》博文中我们已经知道 SpringBootApplication 注解中包含了 EnableAutoConfiguration 注解因此被 SpringBootApplication 注解标注的类也可作为参数传入。当然primarySources 也可传入其他普通类但只有传入被EnableAutoConfiguration 标注的类才能够开启 Spring Boot 的自动配置。 有些朋友可能对 primarySources 这个可变参数的描述有点疑惑下面我们就用实例来演示以其他引导类为入口类进行 Spring Boot 项目启动 首先我们在入口类 DemoApplication 的同级目录创建一个SecondApplication类使用 SpringBootApplication 进行注解。 SpringBootApplication public class SecondApplication { }然后将 DemoApplication 修改成如下 public class DemoApplication {public static void main(String[] args) {SpringApplication.run(SecondApplication.class, args);} }最后我们来运行 DemoApplication 的 main 方法。 从上图可以看出我们的应用依然能正常启动并完成自动配置。因此决定 Spring Boot 启动的入口类并不是一定是 main 方法所在类而是直接或间接被 EnableAutoConfiguration 标注的类。 翻看 SpringApplication 的源码我们在其中还能看到它提供了追加 primarySources 的方法如下所示 public void addPrimarySources(CollectionClass? additionalPrimarySources) {this.primarySources.addAll(additionalPrimarySources); }如果采用 1 中最后的方式启动 Spring Boot 我们就可以调用 addPrimarySources 方法来追加额外的 primarySources。 我们继续回到 SpringApplication 的构造方法里可以看到如下的代码 this.primarySources new LinkedHashSet(Arrays.asList(primarySources));上述这里将 primarySources 参数转换为 LinkedHashSet 集合并赋值给SpringApplication 的私有成员变量 SetClass? primarySources。 知识点 LinkedHashSet 是 Java 集合框架中的类它继承自 HashSet因此具有哈希表的查找性能。这是一个同时使用链表和哈希表特性的数据结构其中链表用于维护元素的插入顺序。也即是说当你向 LinkedHashSet 添加元素时元素将按照添加的顺序被存储并且能够被遍历输出。 此外LinkedHashSet 还确保了 元素的唯一性即重复的元素在集合中只会存在一份。 如果需要频繁遍历集合那么 LinkedHashSet 可能会比 HashSet 效率更高因为其通过维护一个双向链表来记录元素的添加顺序从而支持按照插入顺序排序的迭代。但需要注意的是LinkedHashSet 是非线程安全的如果有多个线程同时访问该集合容器可能会引发并发问题。 2.2 Web 应用类型推断 我们继续往下翻看源码这里调用了 WebApplicationType 的deduceFromClasspath 方法来进行 Web 应用类型的推断。 this.webApplicationType WebApplicationType.deduceFromClasspath();我们继续翻看 WebApplicationType 的源码 public enum WebApplicationType {// 非Web应用类型NONE,// 基于Servlet的Web应用类型SERVLET,// 基于reactive的Web应用类型REACTIVE;private static final String[] SERVLET_INDICATOR_CLASSES { javax.servlet.Servlet,org.springframework.web.context.ConfigurableWebApplicationContext };private static final String WEBMVC_INDICATOR_CLASS org.springframework.web.servlet.DispatcherServlet;private static final String WEBFLUX_INDICATOR_CLASS org.springframework.web.reactive.DispatcherHandler;private static final String JERSEY_INDICATOR_CLASS org.glassfish.jersey.servlet.ServletContainer;static WebApplicationType deduceFromClasspath() {if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null) !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {return WebApplicationType.REACTIVE;}for (String className : SERVLET_INDICATOR_CLASSES) {if (!ClassUtils.isPresent(className, null)) {return WebApplicationType.NONE;}}return WebApplicationType.SERVLET;} }WebApplicationType 是一个定义了可能的Web应用类型的枚举类该枚举类中包含了三块逻辑 枚举类型 非 Web 应用、基于 Servlet 的 Web 应用和基于 reactive 的 Web 应用。用于下面推断的常量推断类型的方法 deduceFromClasspath 当 DispatcherHandler 存在并且 DispatcherServlet 和 ServletContainer 都不存在则返回类型为 WebApplicationType.REACTIVE。当 Servlet 或 ConfigurableWebApplicationContext 任何一个不存在时则说明当前应用为非 Web 应用返回 WebApplicationType.NONE。当应用不为 reactive Web 应用并且 Servlet 和ConfigurableWebApplicationContext 都存在的情况下则返回 WebApplicationType.SERVLET。 在上述的 deduceFromClasspath 方法中我们可以看到在判断的过程中使用到了 ClassUtils 的 isPresent 方法。该工具类方法就是通过反射创建指定的类根据在创建过程中是否抛出异常来判断该类是否存在。 2.3 加载 BootstrapRegistryInitializer this.bootstrapRegistryInitializers new ArrayList(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));上述逻辑用于加载并初始化 BootstrapRegistryInitializer 及其相关的类。 BootstrapRegistryInitializer 是 Spring Cloud Config 的组件之一它的作用是在应用程序启动时初始化 Spring Cloud Config 客户端。 在 Spring Cloud Config 中客户端通过向配置中心Config Server发送请求来获取应用程序的配置信息。而 BootstrapRegistryInitializer 就是负责将配置中心的相关信息注册到 Spring 容器中的。 由于篇幅有限有关 BootstrapRegistryInitializer 更详细的内容笔者后续专门讲解。 2.4 加载 ApplicationContextInitializer setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));上述代码用于加载并初始化 ApplicationContextInitializer 及其相关的类。 ApplicationContextInitializer 是 Spring 框架中的一个接口它的主要作用是在Spring容器刷新之前初始化 ConfigurableApplicationContext。这个接口的实现类可以被视为回调函数它们的 onApplicationEvent 方法会在Spring 容器启动时被自动调用从而允许开发人员在容器刷新之前执行一些自定义的操作。 例如我们可能需要在这个时刻加载一些配置信息或者对某些 bean 进行预处理等。通过实现 ApplicationContextInitializer 接口并重写其onApplicationEvent 方法就可以完成这些定制化的需求。 由于篇幅有限有关 ApplicationContextInitializer 更详细的内容笔者后续专门讲解。 2.5 加载 ApplicationListener setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));上述代码用于加载并初始化 ApplicationListener 及其相关的类。 ApplicationListener 是 Spring 框架提供的一个事件监听机制它是Spring 应用内部的事件驱动机制通常被用于监控应用内部的运行状况。其实现的原理是 观察者设计模式该设计模式的初衷是为了实现系统业务逻辑之间的解耦从而提升系统的可扩展性和可维护性。 我们可以通过自定义一个类来实现 ApplicationListener 接口然后在这个类中定义需要监听的事件处理方法。当被监听的事件发生时Spring 会自动调用这个方法来处理事件。例如在一个 Spring Boot 项目中我们可能想要在容器启动时执行一些特定的操作如加载配置等就可以通过实现 ApplicationListener 接口来完成。 由于篇幅有限有关 ApplicationListener 更详细的内容笔者后续专门讲解。 2.6 推断应用入口类 最后一步调用 SpringApplication 的 deduceMainApplicationClass 方法来进行入口类的推断 private Class? deduceMainApplicationClass() {try {StackTraceElement[] stackTrace new RuntimeException().getStackTrace();for (StackTraceElement stackTraceElement : stackTrace) {if (main.equals(stackTraceElement.getMethodName())) {return Class.forName(stackTraceElement.getClassName());}}} catch (ClassNotFoundException ex) {// 这里捕获异常并继续执行后续逻辑}return null; }上述代码的思路就是 首先创建一个运行时异常并获得其堆栈数组。接着遍历数组判断类的方法中是否包含 main 方法。第一个被匹配的类会通过Class.forName 方法创建对象并将其被返回。最后将上述创建的 Class 对象赋值给 SpringApplication 的成员变量 mainApplicationClass。 总结 本篇 Huazie 带大家初步了解了 SpringApplication 的实例化过程当然由于篇幅受限还有些内容暂时无法详解Huazie 将在后续的博文中继续深入分析。 只有了解 Spring Boot 在启动时都做了些什么我们才能在后续的实践的过程中更好地理解其运行机制以便遇到问题能更快地定位和排查使我们应用能够更容易、更方便地接入 Spring Boot 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kuboard部署启用3个etcd(k8s单个master)

环境:OS:Centos 7拓扑:1master 2nodes1.node节点打标签在集群中 Master Role 节点不足3个个时, 需要在 worker 节点添加 k8s.kuboard.cn/role=etcd 的标签,使etcd最少为奇数3个节点。 查看当前的集群环境[root@maste…

odoo18应用、队列服务器分离(SSHFS) - 详解

odoo18应用、队列服务器分离(SSHFS) - 详解2025-09-30 09:33 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: b…

数据库服务分布架构(MyCAT)

数据库服务分布架构(MyCAT)1.18.1数据库服务分布架构概述介绍分布式架构理念:(基于业务逻辑分布式/基于程序逻辑分布式)●架构演变过程早期,为了满足主要业务功能需求,可以将所有程序部署在一个服务器节点上;架构…

题解:P14038 [PAIO 2025] Adventure Plan

P14038:差分约束、最短路、负环。第一次给官方比赛投题,来写发题解 /se 子任务 \(1,3,4\) 随便乱做就好了,没啥技术含量。 设 \(x_u\) 表示从 \(0\) 到 \(u\) 路径的长度,那么一条有向边 \(u\stackrel{[l,r]}{\to}…

20231414_王仕琪_密码技术密码杂凑算法学习笔记

20231414_王仕琪_密码技术密码杂凑算法学习笔记

网站备案关闭网站高性能网站开发 书籍

在数字化时代,数据存储的重要性不言而喻。然而,有时候我们会遭遇一些意想不到的困扰,比如存储在D盘的数据突然消失。这不仅可能导致重要文件的丢失,还可能影响我们的工作和生活。本文将探讨D盘数据消失的可能原因,提供…

做一家网站需要多少钱网站建设和app开发

函数是对程序逻辑进行结构化或过程化的一种编程方法。能将整块代码巧妙地隔离成易于管理 的小块,把重复代码放到函数中而不是进行大量的拷贝--这样既能节省空间,也 有助于保持一致性,因为你只需改变单个的拷贝而无须去寻找再修改大量复制代码…

租赁服务器做电影网站网站开发的税率

1、链接测试:a:进入页面后点击链接是否正常跳转 b:单独将链接复制到浏览器里面是否正常展示页面(如果需要登录的网站,还需要考虑个人中心等需要登录的功能在未登录成功时以及登录成功后直接通过链接打开的情况) 2、菜单测试&#…

做宠物服务的相关网站简单的购物网站设计

转载自 关于Spring底层原理面试的那些问题,你是不是真的懂Spring? 1.什么是 Spring 框架?Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。Spring帮助开发者解…

深圳网站制作服什么是电子商务网站开发

10日,记者从市教育局获悉,我市中招理化生实验操作考试、信息技术考试时间确定,分别在4月1日至23日、4月1日至30日举行。“目前,城市区义务教育学校已完成属地化管理工作。为进一步做好城市区中招工作,提高工作效率&…

调度算法易错概念总结

临界区是指进程中用于访问临界资源的那段代码 临界区时指并发进程访问共享变量段段那段代码 不需要信号量就能实现的功能是进程的并发执行并发进程如果不经过处理是异步的,因此要进行同步互斥锁是用来解决临界区的问题…

响应式网站搭建开发app平台需要多少钱

自动驾驶建图–道路边缘生成方案探讨 一、背景 对于自动驾驶来说,建图是必不可少的,目前主流厂商技术都在从HD到"无图"进行过渡筹备中,不过想要最终实现真正的"无图"还是有很长的一段路要走。 对于建图来说,…

堆设置了8G,java进程却占用了12G内存

简单来说,当你的JVM堆内存(Heap)使用了8GB时,整个Java进程实际占用的物理内存(常被称为RSS - Resident Set Size)会远大于8GB。一个合理的估算是在 10GB 到 12GB 之间,甚至可能更高,具体取决于你的应用特性和J…

Huxe 推出主动式 AI 音频服务,无感内容消费;OpenAI 推出 ChatGPT Pulse:主动提供个性化信息丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 , 每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术」、「有亮点的产品」、「有思考的文章」、「有…

厦门旅游网站建设目的哈尔滨网站设计哪里有做

什么是数据结构?数据结构是什么?要了解数据结构,我们要先明白数据和结构,数据就是一些int char 这样的变量,这些就是数据,如果你是一个篮球爱好者,那么你的球鞋就是你的数据,结构就是…

C++学习:C++类型转换专栏 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

网站多域名怎么做北京建机职业技能鉴定中心证书查询

1、 你有几次遇到需要解压 .tar 文件但无法记住所需的确切参数?别名可以帮助你!只需将以下内容添加到 .bash_profile 中,然后使用 untar FileName 解压缩任何 .tar 文件。 alias untartar -zxvf 2、 下载文件时,如果出现问题想要…

太原网站建设找山西云起时企业宣传片拍摄思路

小弟多次想把调用门和RPL分开单独说,但几次尝试都没有成功,我发现它们之间是紧偶合、密不可分,RPL的产生主要是为解决系统调用时的“越权”问题,系统调用的实现方式中,以调用门和中断门最为适合。由于以后我们将用中断…

网站不能上传附件ps软件下载中文版免费下载

面向对象 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法:类中定义的函数。类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实…

kubelet源码阅读(三)——kubelet调用device plugin的allocate接口

kubernetes-master/pkg/kubelet/cm/devicemanager/endpoint.go 入参:devs是设备ID 响应:AllocateResponse包含了需要注入到容器中的工作件(envs环境变量、mounts挂在信息、devices设备信息、annotations注解信息、c…