news 2026/9/26 7:20:59

Spring Boot项目创建的5种方式:从Initializr到手工Maven全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot项目创建的5种方式:从Initializr到手工Maven全解析

我平时最常被问到的 Spring Boot 项目创建方式,不是“SpingBoot 怎么写接口”,而是“项目到底怎么建出来”。尤其当你同时要开新微服务、给同事搭演示工程、或者准备自动化批量样板代码的时候,创建方式选对了,能省下的时间是以小时计的。Spring Boot 项目创建大约有五条常见路径:网页端 Spring Initializr、IDEA 内置向导、curl 调用 Initializr API、手工 Maven 工程,以及 Spring Boot CLI 脚手架。这篇我把每条路径的操作细节、底层逻辑和踩坑点都拆开讲清楚,适合刚入门的 Spring Boot 新手,也适合被困在公司内网、或者需要批量生成项目的团队老手。

1. 网页端 Spring Initializr:零成本拿到官方骨架

1.1 从 start.spring.io 到项目压缩包,只需要五分钟

访问 https://start.spring.io,这个页面本身就是 Spring 官方团队维护的 Initializr 服务。你看到的页面左边是项目类型、语言、Spring Boot 版本,右边是项目元数据,最下面是依赖勾选,点 Generate 就能下载一个 zip 压缩包。整个过程不需要本地环境有任何额外配置,这也是我推荐新手第一课就用它的原因——哪怕机器上只有 IDEA 和一张空桌子,也能先把项目“变”出来。

具体选项,按我常用的组合说一遍:

  • Project 选 Maven。Gradle 也很好,但当前绝大多数教程和企业级骨架还是 Maven 占主流。
  • Language 选 Java,这是最不容易出错的默认项。
  • Spring Boot 版本选当前稳定 3.x。以 2025 年初的时间节点看,3.3、3.4、3.5 这些版本都还算活跃,3.5 已经支持 Java 21 虚拟线程,如果你本机装的是 Java 21,直接选 3.5 系列。
  • Group 填反写域名,比如 com.example;Artifact 填项目名,比如 order-service。这两项会决定最终的 Package name,也就是代码根包名。
  • Java 版本按本机 JDK 选。Spring Boot 3.x 最低要求 17,建议直接 17 或 21。
  • Dependencies 里,Web 是打底,写接口必选;参数校验再加 Validation;要连数据库就加 Data JPA 和对应驱动;要监控再加 Actuator。

填完点击 Generate,下载下来的压缩包通常叫 artifactId.zip。这个页面看似简单,其实背后藏着一个关键逻辑:网页端本质上只是给 Spring Initializr 的 REST API 套了一层 UI,你在页面上看到的每个选项,最终都会变成 URL 上的一个参数。这一点后面讲 curl 时还会再用到。

1.2 项目元数据选错带来的连锁反应

Group、Artifact、Package name 这三项是新手最容易忽略的。很多人随手填一个 abc 就生成了项目,结果后面代码越写越乱,要改包名时发现成本特别高。

Package name 一旦生成,后续你写的 Controller、Service、Mapper 都要放在这个包下面,因为 Spring Boot 的组件扫描默认以主启动类所在包为根,向上扫描所有子包。包名起得随意,轻则团队代码风格混乱,重则启动时组件扫描范围对不上,出现“明明写了 @Service,但装配时找不到 Bean”这种问题。所以建项目的第一分钟就把包名定好,比什么都重要。

我自己的习惯是:Group 用公司统一域名反写,Artifact 用业务模块名,Package name 再单独指定成com.company.module,不要把 Artifact 里带的下划线或短横线混进包名里。这样生成出来的目录层级干净,后面写代码时不容易出现包路径和模块名互相打架的情况。

1.3 拿到压缩包后的骨架解读

解压后你会看到这样一个标准结构:

demo ├── .mvn ├── src │ ├── main │ │ ├── java/com/example/demo │ │ │ └── DemoApplication.java │ │ └── resources │ │ ├── static │ │ ├── templates │ │ └── application.properties │ └── test/java/com/example/demo │ └── DemoApplicationTests.java ├── .gitignore ├── HELP.md ├── mvnw ├── mvnw.cmd └── pom.xml

这里最值得先看懂的是 DemoApplication.java 和 pom.xml。DemoApplication 上的 @SpringBootApplication 是由 @Configuration、@EnableAutoConfiguration、@ComponentScan 三个注解组合而成的,是自动配置和组件扫描的入口。pom.xml 则声明了 spring-boot-starter-parent 和 spring-boot-starter-web,之后所有依赖的版本管理基本都由 parent 统一控制。

导入 IDEA 时有个小细节:不要直接 File → Open 选整个文件夹,要选中里面的 pom.xml 文件,让 IDEA 识别成 Maven 项目,右侧 Maven 工具窗口才会加载出来,后续依赖刷新、打包操作都在那里操作。用 Gradle 版本同理,选 build.gradle 或 settings.gradle 导入。

2. IDEA 2024 内置向导:日常开发用得最多的一条路径

2.1 新建 Spring Boot 项目时的完整操作和界面差异

IDEA 2024 系列的 New Project 向导比老版本改了不少。具体路径是:File → New → Project,左侧面板选择 Spring Boot,右侧配置语言、类型、JDK、Spring Boot 版本,依赖区域勾选需要的组件,最后点 Create。老版本的“New Project → Spring Initializr → 填 URL 和元数据”的界面在新版里被整合进了更图形化的流程,对新手更友好,但本质上调用的还是同一个在线 Initializr 服务。

这里要特别说明一个容易混淆的地方:IDEA 的“Spring Boot”创建入口并不是 IDEA 自己本地生成了一个项目,而是它替你向 start.spring.io 发送请求,把返回的骨架工程落到本地目录。换句话说,IDEA 只是把网页端 Initializr 包装成了 GUI。只要是这个过程,就非常依赖 IDEA 当前网络能否正常访问 start.spring.io。

IDEA Ultimate 自带完整的 Spring 支持,Community 版本默认没有内置 Spring Initializr 向导。如果你用的是 Community 版,打开 New Project 时发现根本没有 Spring Boot 选项,不要怀疑自己装错了版本,这就是功能差异。解决办法要么换 Ultimate,要么在 Community 里安装第三方 Spring 插件,要么直接用第一节的网页端方案,生成后导入 IDEA——这反而是我在 Community 环境里最常用的方式。

2.2 “无法创建新的项目”这类警告的完整排查链路

网上关于 IDEA 2024 创建 Spring Boot 项目失败的问题很多,有人截图报“警告:无法创建新的项目”,有的版本还会带错误编号。这类问题绝大多数不是 IDEA 坏了,而是它连不上 start.spring.io。排查链路我建议按下面顺序走,每一步都很快:

  1. 先确认 JDK。Project Structure 里设置 Project SDK 为 17 或 21,如果本机只有一个 JDK 8,那 Spring Boot 3.x 项目必然创建失败。Spring Boot 2.7 还能勉强配合 JDK 8,但 3.x 起 JDK 17 是硬底线。
  2. 再确认网络。用浏览器直接打开 start.spring.io,如果能打开,说明网络基本通畅;如果打不开,那 IDEA 里的创建向导大概率也会失败。
  3. 检查 IDEA 的 HTTP 代理设置。Settings → Appearance & Behavior → System Settings → HTTP Proxy,如果公司网络要求走内部代理,要在这里正确配置;如果是本机直连,保持自动检测就行。这一步不是为了让你动什么特殊网络工具,纯粹是排查 IDEA 是否错误地走了代理导致请求失败。
  4. 清理 IDEA 缓存。File → Invalidate Caches → Invalidate and Restart,等重启后再试。
  5. 切换 Initializr 地址。IDEA 创建向导里如果能看到 Service URL,把https://start.spring.io换成https://start.aliyun.com,这是阿里云维护的 Initializr 镜像,对国内网络更友好。换完再创建,成功率会高很多。

最后还有一类情况:IDEA 里能正常创建项目,但创建完一直卡在下载依赖。这往往不是 IDEA 的问题,而是 Maven 中央仓库访问太慢,属于网络环境问题。建议在 Maven 的 settings.xml 里配置国内镜像仓库,比如阿里云 Maven 镜像,这个和项目创建本身是两件事,但很多人把它混在一起排查,白白浪费了不少时间。

2.3 创建之后的第一次启动实践

项目创建成功后,我第一次跑 Spring Boot 项目的习惯是先不写任何业务代码,直接启动一次,确认基础环境没问题。在 IDEA 右侧 Maven 窗口找到demo/DemoApplication,右键 Run,或者直接打开 DemoApplication.java 点 main 方法旁边的绿色三角。

第一次运行时,Maven 会下载大量依赖,耗时一两分钟很正常。如果中途失败,看控制台最底下的 Error 原因,绝大多数是网络下载超时。处理办法是先确认 settings.xml 里的镜像仓库配置生效,再执行一次mvn clean compile,让依赖提前拉完整,然后再回 IDEA 启动。

启动成功的标准是控制台出现类似Started DemoApplication in 1.5 seconds的日志,并且 8080 端口被占用。此时访问http://localhost:8080如果返回 Whitelabel Error Page,那不是出错,反而说明 Web 容器已经正常起来了,只是还没写任何接口而已。

3. curl 直接调用 Initializr:适合脚本化和批量生成的玩法

3.1 一条 curl 命令把项目拉下来

如果你不想要网页端的点点点,也不想被 IDE 向导拴住,可以直接用 curl 调用 Spring Initializr 的 REST API。一条命令就能生成一个标准和网页端完全相同的项目压缩包:

curl https://start.spring.io/starter.zip \ -d type=maven-project \ -d language=java \ -d bootVersion=3.3.5 \ -d groupId=com.example \ -d artifactId=course-demo \ -d name=course-demo \ -d packageName=com.example.coursedemo \ -d javaVersion=17 \ -d dependencies=web,validation,data-jpa \ -o course-demo.zip

执行完,当前目录会多出一个 course-demo.zip。然后:

unzip course-demo.zip -d course-demo cd course-demo ./mvnw spring-boot:run

项目就正常启动了。这套流程没有任何图形界面,完全可以在 SSH 终端或者 CI 脚本里运行。

参数说明一下:-d type=maven-project代表生成 Maven 工程,改成type=gradle-project就是 Gradle 工程;bootVersion指定 Spring Boot 版本;groupId、artifactId、packageName对应网页上的项目元数据;javaVersion指定 JDK 版本;dependencies用逗号分隔多个依赖,比如 web、data-jpa、validation 之间不要加空格。如果不传 bootVersion,Initializr 会返回当前默认的稳定版本;如果不传 javaVersion,则按 Boot 版本匹配一个合理默认值。

3.2 不想记参数的快速技巧:先看 metadata

curl 方案最大的门槛是记参数。其实 Initializr 提供一个元数据接口,能把你所有可选字段一次性列出来:

curl -H "Accept: application/json" https://start.spring.io/metadata/client

返回的是一个大 JSON,里面包含支持的 Boot 版本列表、Java 版本列表、依赖列表等。依赖列表里能看到依赖的 id、名称、描述,比如 web 的 id 就是web,我写进-d dependencies=web里的 web 就是这么来的。这个接口很适合脚本里做动态校验,比如你在 CI 里加了依赖,可以先检查当前 Initializr 是否认识这个依赖 id,避免创建完才发现依赖没生效。

3.3 批量生成和团队标准化的关键习惯

curl 方式真正的价值在批量场景。比如公司要一次性初始化五个微服务工程,我一般会在一个 shell 脚本里循环处理:

for svc in order-service product-service user-service gateway-service auth-service; do mkdir -p $svc && cd $svc curl https://start.spring.io/starter.zip \ -d type=maven-project \ -d language=java \ -d bootVersion=3.3.5 \ -d groupId=com.company \ -d artifactId=$svc \ -d name=$svc \ -d packageName=com.company.$svc \ -d javaVersion=21 \ -d dependencies=web,validation,actuator \ -o $svc.zip unzip -o $svc.zip && rm $svc.zip cd .. done

这里有一个容易被忽略的经验:在脚本里创建项目时绝对不要省略 bootVersion 和 javaVersion。如果不固定版本,不同时间创建的项目可能带着不同版本的 Boot 骨架,互相之间合并代码时会出现莫名其妙的父 POM 版本冲突。把版本固定住,就是给团队统一技术基线,这一步在微服务数量多的时候尤其重要。

4. 手工 Maven 工程:最能理解 Spring Boot 本质的方式

4.1 一个最简单的 pom.xml 长什么样

手工从零创建 Spring Boot 项目,不是说不能生成文件,而是你要理解每个文件为什么存在。最直接的方式是建一个空目录,自己在里面写 pom.xml 和启动类,完全不依赖 Initializr。最简的 pom.xml 长这样:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.5</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>handmade-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

这个 pom.xml 的核心是继承了spring-boot-starter-parent。这个父 POM 做了两件大事:一是替所有 Spring Boot 官方依赖锁定了版本,所以你写 spring-boot-starter-web 时不需要再填 version 标签;二是配置了编译插件和资源处理相关的默认行为。

如果你所在的团队用的是自建父 POM,不方便继承 spring-boot-starter-parent,还有一种替代方案:在自己项目的 dependencyManagement 里显式导入org.springframework.boot:spring-boot-dependencies,效果类似,由它来统一管理版本。技术上是这两条路二选一,具体看公司 Maven 工程规范。

4.2 主启动类和插件为什么不能省

pom.xml 之外,还要自己写两个核心文件。

启动类:

package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class HandmadeDemoApplication { public static void main(String[] args) { SpringApplication.run(HandmadeDemoApplication.class, args); } }

测试接口:

package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "hello spring boot"; } }

启动类上的@SpringBootApplication决定了程序从哪里开始扫描组件,所以它的包路径就是后续所有业务类的根包路径。spring-boot-maven-plugin则是打包阶段必需的插件,它能把应用重新打包成可执行 fat jar,也就是说mvn package之后生成的 jar 可以直接java -jar运行,而默认的 Maven jar 插件做不到这件事。

手工搭建过程中,我最想提醒的就是不要图省事省略 parent 或插件。网上很多老教程为了“简化”会把 parent 去掉,自己一个个锁版本,结果启动时依赖版本冲突,排查成本远高于当时省下的几行配置。

4.3 垂直场景:离线环境和内网里的唯一靠谱方案

手工 Maven 创建方式还有一个不可替代的场景:离线环境。比如有些公司和高校的机房完全隔离外网,连 start.spring.io 都访问不到,此时网页端和 IDEA 向导都会失效。手工写 pom.xml 是唯一能绕开的方案,只要本地 Maven 仓库或者公司内部 Nexus 私服里有对应的依赖包,项目就能正常构建。

在内网环境里手工搭项目时,我还有一个习惯:项目目录下先不放业务代码,而是只放 pom.xml、启动类和一个测试类,然后跑一遍mvn dependency:go-offline。这个命令会把项目所有依赖提前拉进本地仓库,后面断网状态下再编译也能正常工作,配合离线仓库镜像,整个创建流程跟在线环境基本没区别。

5. Spring Boot CLI:老牌命令行脚手架,今天怎么用

5.1 安装与基础用法

Spring Boot CLI 是官方曾经提供的一个独立命令行工具,最早的设计目标是让开发者不写传统 Maven 工程,直接用 Groovy 脚本快速跑 Spring Boot 应用。后面演进中,它还提供了spring init子命令,用来生成标准项目骨架。

安装方式很简单,用 SDKMAN 是最主流的:

sdk install springboot

安装完验证一下:

spring --version

传统 CLI 时代,生成项目的命令大概是这样的:

spring init --build=maven --java-version=17 --dependencies=web,data-jpa demo

这个命令会在当前目录生成一个名为 demo 的 Spring Boot Maven 项目。它的底层同样是在调用 start.spring.io,和 curl 请求本质相同,只是把参数封装得更友好,还自带解压环节。

5.2 CLI 的版本边界和现实定位

这里必须讲清楚版本变化:Spring Boot 官方在 3.4 版本发布说明里明确把 Spring Boot CLI 标记为弃用,并计划在 4.0 版本移除。也就是说,如果你用的是 3.4 或更新的版本,传统spring init相关能力已经不在长期支持计划里,还在用旧命令的同学要么锁定在旧版本,要么就该把创建逻辑迁到 curl 或独立 Initializr CLI 上。

很多旧教程还在教spring init,练手时容易产生困惑:命令根本不存在,或者提示被移除。这不是你写错了,而是工具链已经更新换代。单纯从创建项目这个需求看,curl 调用 Initializr API 完全能覆盖 CLI 的活儿,甚至更透明、更可控。CLI 更像是一种历史的便利层,理解了它的存在背景和弃用方向,就不会在选型时盲目追新。

5.3 我对 CLI 的真实态度

用我个人体感来说,我不反对尝鲜 CLI,但真到了团队协作层面,CLI 的定位比较尴尬。日常开发有 IDEA 向导就够了,需要自动化时 curl 脚本更直接,CLI 反而是中间态:比 IDE 快一点,比 curl 少一点灵活性。真要提升团队效率,我建议把精力放在维护一套公司内部的项目模板仓库上,而不是每次都用 CLI 或 curl 从零生成。

模板仓库的思路是:第一次用 Initializr 生成一个标准工程,把所有通用依赖、统一包名、公共工具类、日志规范都配置好,然后推到一个专门的 Git 仓库。后续新项目只做两步:clone 模板仓库,全局替换项目名。这样产生的骨架比任何 CLI 初始化的工程都更贴合团队规范,也规避了不同时期的 Initializr 默认版本漂移问题。

6. 五种方式横向对比与最终选型建议

6.1 一张表看明白五种方式的差异

创建方式是否需要联网上手难度自动化程度最合适场景
网页端 Initializr需要最低低新手入门、偶发建项目
IDEA 内置向导需要低中日常开发、个人/小团队
curl 调用 API需要中高脚本化、批量生成、CI
Maven 手工构建不需要中高低离线/内网、理解原理
Spring Boot CLI需要中中命令行爱好者、旧版熟悉路径

依赖网络这一点上,除了手工 Maven 构建外,其余四种多少都要访问各种网络服务。所以如果你所在网络访问 start.spring.io 不方便,优先级就应该调整:先试 IDEA 里切换阿里云镜像,再不行就用 curl 请求 mirror 生成文件;如果完全离线,只能走手工 Maven 路线,靠本地仓库和私服解决依赖。

6.2 给三类读者的具体选择建议

如果你刚学 Spring Boot,我的建议是先别管什么 CLI 和 curl。打开官网,或者直接用 IDEA 向导建一个项目,看一遍生成出来的目录结构,然后把里面的 pom.xml 和启动类读一遍。这个阶段最重要的是把项目跑起来,而不是追求用什么姿势创建。

如果你在团队里要批量初始化微服务,我建议直接上 curl 方案,写一个脚本把统一 groupId、统一 Boot 版本、统一依赖串起来。脚本提交到 Git 仓库后,以后任何人建新服务不用再问“这里怎么选”,跑一遍脚本就有标准骨架。这个好处随着微服务数量增加会越来越明显。

如果你身处离线环境,或者你的公司有严格的依赖安全管理,手工 Maven 方案才是压舱石。自己写的 pom.xml 完全在本地生成,不依赖任何第三方服务,配合私服把依赖锁死,是最可控的一种方式。

6.3 一个长期有用的小习惯:把“标准依赖清单”固定下来

最后分享一个我用了很久的习惯:在项目初始化时,不要每次临时想“我要勾哪几个依赖”,而是把团队常用的一组依赖固定下来。比如 web、validation、data-jpa、lombok、actuator、test、configuration-processor,把这些登录到一个文档或者直接写进 curl 脚本参数里。

这样做的原因是,Spring Boot 的依赖一旦选错,后面补的代价不只是加一行 pom 的问题。比如漏了 validation 依赖,启动时@Valid注解完全不生效;漏了 actuator,生产环境的健康检查接口直接 404。先把清单固定住,生成后再按业务实际增删,效率会高很多。

我在实际操作中感受最深的一点,是不要神化任何一种创建方式。网页端、IDE、curl、手工、CLI,本质上都是“把 Spring Boot 工程的标准骨架拿到本地”的途径。比选哪个途径更重要的,是你是否清楚这个骨架里每个文件的职责。一个能手写 pom.xml 的人,再回到网页端生成项目时,会更清楚自己勾选的东西到底影响了什么;反过来,一个只会点 Next 的新手,遇到创建失败时也更容易被表面的报错误导。所以我的建议是:先用网页端或 IDEA 把项目跑起来,然后找时间手工搭一个最简工程,把所有疑问从根上解决掉。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 7:19:36

AI获客系统不占本地配置?深度实测云端SaaS与本地部署的成本真相

1. "不占本地配置"这句话的三种正确解读——先别急着下单&#xff0c;搞懂它省略了什么前阵子一位做制造业的朋友被某AI获客系统的销售缠了一个星期&#xff0c;对方反复强调"这套系统完全不用买服务器&#xff0c;你们现有电脑就能跑&#xff0c;真不占本地配置…

作者头像 李华
网站建设 2026/9/26 7:19:11

SSVEP空间滤波全解析:从CCA到TRCA的脑机接口实战指南

简介&#xff1a;面向脑机接口与脑电信号处理研究者的SSVEP空间滤波算法包&#xff0c;集中实现多种典型相关分析及其变体。资源覆盖标准典型相关分析、扩展典型相关分析、多重刺激典型相关分析、多通道典型相关分析、L1正则化多通道典型相关分析以及多数据集典型相关分析等主流…

作者头像 李华
网站建设 2026/9/26 7:18:54

Java开发者转型AI Agent工程师:Spring AI进阶路线与15个实战方向

1. 从Java开发者到AI Agent工程师&#xff1a;这条路到底该怎么走这两年跟不少做Java的朋友聊过&#xff0c;大家普遍有个焦虑&#xff1a;AI这波浪潮来了&#xff0c;Python阵营的人好像天然占优势&#xff0c;写Java的是不是要被落下了&#xff1f;我一开始也有这个担心&…

作者头像 李华
网站建设 2026/9/26 7:18:52

零基础Python第一次作业:从环境配置到可视化入门

1. 装好Python和编辑器&#xff0c;是第一次作业的真正拦路虎很多人拿到"Python第一次作业"这个题目时&#xff0c;第一反应是赶紧找一份源码抄上去了事。但我见过太多同学&#xff0c;卡在的不是代码本身&#xff0c;而是连Python环境都没装明白。双击安装包一路点&…

作者头像 李华
网站建设 2026/9/26 7:18:21

测试自动化进阶实战:从工具选型到AI辅助的专家成长路径

1. 高薪自动化测试专家的能力拼图&#xff1a;技术只是入场券先说个扎心的现象。同样叫"测试工程师"&#xff0c;有人每天在重复点按钮、填表单、核对页面样式&#xff0c;一年下来简历上只能写"熟悉功能测试流程"&#xff1b;有人却在搭建自动化测试框架、…

作者头像 李华
网站建设 2026/9/26 7:18:11

Rocky Linux 9.1 生产级网络与安全配置实战指南

1. 这不是一份“安装完就扔”的配置手册&#xff0c;而是一套能扛住生产环境拷问的 Rocky Linux 9.1 网络底盘Rocky Linux 9.1 是 CentOS 停更后&#xff0c;企业级服务器领域最被寄予厚望的稳定替代方案。它不是 Red Hat Enterprise Linux 的简单复刻&#xff0c;而是由社区主…

作者头像 李华