当前位置: 首页 > news >正文

Spring Boot 项目中 Maven 剔除无用 Jar 引用的最佳实践

目录

  1. 引言
  2. Maven 依赖管理的基础概念
    • 2.1 什么是 Maven 依赖
    • 2.2 Maven 的依赖传递机制
  3. 无用依赖的常见问题与影响
  4. 剔除无用 Jar 引用的常见方法
    • 4.1 识别无用依赖
    • 4.2 使用 Maven 的 dependency:analyze 插件
    • 4.3 配置 scope 以优化依赖范围
    • 4.4 使用 exclude 排除传递依赖
    • 4.5 分析依赖树
  5. 最佳实践:一步步清理无用 Jar
    • 5.1 基础清理方法
    • 5.2 高级清理方法
    • 5.3 自动化剔除
  6. Spring Boot 特有的优化策略
  7. 总结与展望

引言

在 Spring Boot 项目开发中,Maven 是最常用的构建工具之一。通过 Maven,我们可以轻松地管理项目所需的依赖。然而,随着项目的复杂化,无用的 Jar 包引用可能会逐渐增多,导致构建时间延长、运行效率下降,甚至引发潜在的依赖冲突问题。

本文旨在详细解析如何在 Spring Boot 项目中剔除无用的 Jar 引用,并提供一套系统化的清理和优化方法,帮助开发者构建高效、清晰、轻量化的项目依赖管理体系。


Maven 依赖管理的基础概念

2.1 什么是 Maven 依赖

Maven 依赖是指项目所需的第三方库,通常以 Jar 文件的形式存储在 Maven 仓库中。每个 Maven 项目都有一个 pom.xml 文件,用于声明这些依赖。例如:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.0.0</version>
</dependency>

通过 Maven 的依赖管理功能,可以自动下载并配置这些库。

2.2 Maven 的依赖传递机制

Maven 支持依赖传递机制,即一个依赖可能会自动引入其他依赖。这些通过传递引入的依赖称为“传递依赖”。例如:

  • 项目 A 引入了依赖 B
  • 依赖 B 又引入了依赖 C
  • 那么项目 A 将自动拥有 B 和 C 的功能。

依赖传递可以显著提高开发效率,但也容易导致以下问题:

  • 引入不必要的依赖。
  • 版本冲突。
  • 增加构建时间。

无用依赖的常见问题与影响

3.1 无用依赖的来源

  • 默认依赖:Spring Boot 的 starter 通常包含很多默认依赖,部分功能可能未使用。
  • 传递依赖:引入的第三方库中可能包含无关的传递依赖。
  • 历史遗留:项目早期引入的依赖可能已经不再需要,但仍然存在于 pom.xml 中。

3.2 无用依赖的影响

  • 构建时间变长:无用依赖会增加编译和打包的时间。
  • 运行效率下降:无用的 Jar 包会占用内存和资源,影响运行效率。
  • 潜在冲突:不必要的依赖可能会与核心依赖版本不一致,导致运行时错误。

剔除无用 Jar 引用的常见方法

4.1 识别无用依赖

最基础的方法是手动检查 pom.xml 文件,找出那些不再使用的依赖。这需要对项目的实际代码和功能有深入了解。

4.2 使用 Maven 的 dependency:analyze 插件

Maven 提供了一个内置的 dependency:analyze 插件,可以分析项目中实际使用的依赖,并报告未使用的依赖。例如:

mvn dependency:analyze

运行结果中会显示:

  • Used undeclared dependencies:未声明但已使用的依赖。
  • Declared unused dependencies:声明但未使用的依赖。

示例输出:

[WARNING] Unused declared dependencies found:
[WARNING]    org.apache.commons:commons-lang3:jar:3.12.0:compile

4.3 配置 scope 以优化依赖范围

通过指定依赖的作用范围(scope),可以限制依赖的可见性。例如:

  • compile:默认范围,编译时可见。
  • provided:运行时不打包,仅在编译和测试时可见。
  • runtime:运行时可见,但编译时不可见。
  • test:仅在测试时可见。

示例:

<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>

4.4 使用 exclude 排除传递依赖

可以通过 exclude 标签排除不需要的传递依赖。例如:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions>
</dependency>

4.5 分析依赖树

Maven 的 dependency:tree 命令可以列出项目的完整依赖树,帮助开发者清晰地看到所有依赖及其来源:

mvn dependency:tree

示例输出:

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.6.6:compile
[INFO] |  \- org.springframework.boot:spring-boot-starter-tomcat:jar:2.6.6:compile
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:compile

最佳实践:一步步清理无用 Jar

5.1 基础清理方法

  1. 定期检查依赖:使用 dependency:analyzedependency:tree 工具分析依赖。
  2. 清理历史遗留依赖:移除项目中不再使用的依赖。
  3. 避免不必要的 starter:按需引入 Spring Boot 的 starter,避免默认引入未使用的模块。

5.2 高级清理方法

  • 精简传递依赖:明确需要的传递依赖,排除多余的依赖项。
  • 分模块管理依赖:对于多模块项目,可以通过父子 POM 统一管理依赖,减少重复定义。

5.3 自动化剔除

借助工具如 Maven Enforcer PluginDependabot,可以自动检测无用依赖并提出优化建议。例如:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-enforcer-plugin</artifactId><version>3.0.0</version><executions><execution><id>enforce-no-unused-dependencies</id><phase>validate</phase><goals><goal>enforce</goal></goals></execution></executions>
</plugin>

Spring Boot 特有的优化策略

  1. 精确控制 starter:根据项目需求选择 starter,避免引入多余模块。
  2. 使用自定义依赖:将常用依赖打包成自定义 starter,统一管理和优化依赖。
  3. 定期更新依赖:Spring Boot 的每次更新都会优化其 starter 的默认依赖,跟进最新版本可以减轻冗余依赖。

总结与展望

Maven 的依赖管理是 Spring Boot 项目构建的重要环节,合理清理无用的 Jar 引用,可以显著提高项目的构建效率和运行性能

。通过本文的系统讲解,相信开发者能够更好地掌握依赖优化的方法,构建一个高效、清晰、可维护的项目结构。

未来,随着工具和技术的不断发展,依赖优化的自动化程度将进一步提高,开发者可以将更多精力集中在业务逻辑的开发上,为项目带来更大的价值。

相关文章:

Spring Boot 项目中 Maven 剔除无用 Jar 引用的最佳实践

目录 引言Maven 依赖管理的基础概念 2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机制 无用依赖的常见问题与影响剔除无用 Jar 引用的常见方法 4.1 识别无用依赖4.2 使用 Maven 的 dependency:analyze 插件4.3 配置 scope 以优化依赖范围4.4 使用 exclude 排除传递依赖4.5 分析…...

useWhyDidYouUpdate详解

目录 API Params demo演示 源码 useWhyDidYouUpdate是ahooks库中的一个hook函数&#xff0c;用于帮助开发者排查是哪个属性改变导致了组件的 rerender。 API type IProps Record<string, any>;useWhyDidYouUpdate(componentName: string, props: IProps): void; …...

c++入门——c++输入cin和输出cout的简单使用

c输入cin、输出cout 1 cin2 cout3 cin和cout说明 c在c语言的输入、输出函数的基础上进行了封装。 1 cin c可以理解为控制台&#xff0c;in可以理解为输入。 参考代码&#xff1a; void f(){int a;float b;double c;char d;cin>>a>>b>>c>>d;//这里和…...

Spring Cloud LoadBalancer (负载均衡)

目录 什么是负载均衡 服务端负载均衡 客户端负载均衡 Spring Cloud LoadBalancer快速上手 启动多个product-service实例 测试负载均衡 负载均衡策略 自定义负载均衡策略 什么是负载均衡 负载均衡(Load Balance&#xff0c;简称 LB) , 是高并发, 高可用系统必不可少的关…...

微服务-1 认识微服务

目录​​​​​​​ 1 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 2 服务拆分原则 2.1 什么时候拆 2.2 怎么拆 2.3 服务调用 3. 服务注册与发现 3.1 注册中心原理 3.2 Nacos注册中心 3.3 服务注册 3.3.1 添加依赖 3.3.2 配置Nacos 3.3.3 启动服务实例 …...

基于51单片机的交通灯带拐弯proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1cgqRHMHp9VJet4vs5LiG5A 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…...

1229java面经

1,Java中synchronized关键字是否是可重入的? 可重入的定义 可重入是指当一个线程已经获取了某个对象的锁&#xff0c;在该锁没有释放的情况下&#xff0c;如果这个线程再次请求获取这个对象的锁&#xff0c;是可以成功获取的&#xff0c;而不会出现自己把自己锁死的情况。简单…...

MySQL中查看表结构

1. 使用 DESCRIBE 或 DESC 命令 DESCRIBE&#xff08;或其简写 DESC&#xff09;是最简单和最直接的方法&#xff0c;可以显示表的列信息。 语法&#xff1a; DESCRIBE table_name; -- 或者 DESC table_name;示例&#xff1a; 假设有一个名为 employees 的表&#xff0c;可以…...

python利用selenium实现大麦网抢票

大麦网&#xff08;damai.cn&#xff09;是中国领先的现场娱乐票务平台&#xff0c;涵盖演唱会、音乐会、话剧、歌剧、体育赛事等多种门票销售。由于其平台上经常会有热门演出&#xff0c;抢票成为许多用户关注的焦点。然而&#xff0c;由于票务资源的有限性&#xff0c;以及大…...

FME教程:一键批量调换图斑X、Y坐标,解决因为坐标弄反了,导致GIS弹窗提示“范围不一致”警告问题

目录 一、实现效果 二、实现过程 1.读取数据 2.提取坐标 3.调换图斑的X、Y坐标 4.输出成果 5.模板的使用 三、总结 在工作中有时候会出现因为失误导致图斑的X、Y坐标弄反&#xff0c;在GIS中打开是会提示“范围不一致”警告的弹窗警告&#xff0c;如果重做工作量非常大…...

OpenCV-Python实战(4)——图像处理基础知识

一、坐标 在 OpenCV 中图像左上角坐标为&#xff08;0&#xff0c;0&#xff09;&#xff0c;竖直向下为 Y&#xff08;height&#xff09; &#xff1b;水平向右为 X&#xff08;width&#xff09;。 二、生成图像 2.1 灰度图像 img np.zeros((h,w), dtype np.uint8) i…...

音视频入门基础:MPEG2-PS专题(1)——MPEG2-PS官方文档下载

一、引言 MPEG2-PS&#xff08;又称PS&#xff0c;Program Stream&#xff0c;程序流&#xff0c;节目流&#xff09;是一种多路复用数字音频、视频等的封装容器。MPEG2-PS将一个或多个分组但有共同的时间基准的基本数据流 &#xff08;PES&#xff09;合并成一个整体流。它是…...

Qt自定义步骤引导按钮

1. 步骤引导按钮 实际在开发项目过程中&#xff0c;由一些流程比较繁琐&#xff0c;为了给客户更好的交互体验&#xff0c;往往需要使用step1->step2这种引导对话框或者引导按钮来引导用户一步步进行设置&#xff1b;话不多说&#xff0c;先上效果 2. 实现原理 实现起来…...

贝叶斯神经网络(Bayesian Neural Network)

最近在研究贝叶斯神经网络,一些概念一直搞不清楚,这里整理一下相关内容,方便以后查阅。 贝叶斯神经网络(Bayesian Neural Network) 贝叶斯神经网络(Bayesian Neural Network)1. BNN 的核心思想2. BNN 的优化目标3. BNN 的结构与特点4. BNN 的训练过程5. BNN 的优缺点6. …...

Direct Preference Optimization: Your Language Model is Secretly a Reward Model

DPO直接偏好优化:你的语言模型实际上是一个奖励模型 前言知识储备 什么是用户偏好数据目的:用于指导模型行为,使其输出更符合特定用户或者用户群体期望和喜好的信息。 用户偏好数据通常反映了用户对特定内容、风格、观点或者互动方式的倾向。 用户偏好数据的收集通常涉及直…...

如何通过 Kafka 将数据导入 Elasticsearch

作者&#xff1a;来自 Elastic Andre Luiz 将 Apache Kafka 与 Elasticsearch 集成的分步指南&#xff0c;以便使用 Python、Docker Compose 和 Kafka Connect 实现高效的数据提取、索引和可视化。 在本文中&#xff0c;我们将展示如何将 Apache Kafka 与 Elasticsearch 集成以…...

嵌入式系统 第十二讲 块设备和驱动程序设计

• 块设备是Linux三大设备之一&#xff08;另外两种是字符设备&#xff0c;网络设备&#xff09;&#xff0c;块 设备也是通过/dev下的文件系统节点访问。 • 块设备的数据存储单位是块&#xff0c;块的大小通常为512B至32KB不等。 • 块设备每次能传输一个或多个块&#xff0c…...

攻防世界web第六题upload

这是题目&#xff0c;可以看出是个上传文件的题目&#xff0c;考虑文件上传漏洞&#xff0c;先随便上传一个文件试试&#xff0c;要求上传的是图片。 可以看到上传成功。 考虑用一句话木马解决&#xff0c;构造文件并修改后缀为jpg,然后上传。 <?php eval($_POST[attack])…...

人工智能-Python网络编程-HTTP

用Python创建自己的HTTP服务器 方案一 HTTP-Python官方 python -m http.server 80 方案二 HTTP-概念版 import socketIPV4_ADDR 192.168.124.7 IPV4_PORT 8888# TCP 服务端程序必须绑定端口号&#xff0c;否则客户端找不到这个 TCP 服务端程序 class ServerSocket(obje…...

探索仓颉编程语言:功能、实战与展望

目录 引言 一.使用体验 二.功能剖析 1.丰富的数据类型与控制结构 2.强大的编程范式支持 3.标准库与模块系统 4.并发编程能力 三.实战案例 1.项目背景与目标 2.具体实现步骤 (1).导入必要的模块 (2).发送 HTTP 请求获取网页内容 (3).解析 HTML 页面提取文章信息 (…...

Unity-Editor扩展显示文件夹大小修复版 FileCapacity.cs

实战中是这样的,大项目, 容易定位美术大资产 (原版的代码有问题,每次点运行都会卡顿,大项目20S) //但其实获整个项目内容,1G都没有,有够省的(10年前的中型项目,一直有出DLC) using System; using System.Collections; using System.Collections.Generic; using Sy…...

BLE core 内容整理解释

本文内容比较杂散&#xff0c;只是做记录使用&#xff0c;后续会整理的有条理些 link layer 基本介绍 **Link Layer Control&#xff08;链路层控制&#xff09;**是蓝牙低功耗&#xff08;BLE&#xff09;协议栈的核心部分&#xff0c;负责实现设备间可靠、安全、低功耗的数…...

Linux CPU调度算法

简述 ● CPU数量 < 进程数 ● 每次CPU都要决定下一个运行的进程&#xff0c;这个选择叫做CPU调度&#xff1b;这个选择工作就叫做CPU调度程序 ● 如果一个进程中有多个线程的话&#xff0c;内核管理的线程就以线程为基本单位 ● 进程通常分为两种&#xff0c;一种长时间占…...

Linux套接字通信学习

Linux套接字通信 在网络通信的时候, 程序猿需要负责的应用层数据的处理(最上层)&#xff0c;而底层的数据封装与解封装&#xff08;如TCP/IP协议栈的功能&#xff09;通常由操作系统、网络协议栈或相关网络库&#xff08;如Socket库&#xff09;实现。&#xff08;程序员只需要…...

mybatis-plus 用法总结

MyBatis-Plus&#xff08;简称 MP&#xff09;是 MyBatis 的增强工具&#xff0c;旨在简化开发者的 CRUD 操作。它在 MyBatis 的基础上提供了更多的功能和便利性&#xff0c;如代码生成器、分页插件、性能分析插件等&#xff0c;使开发者能够更高效地进行数据库操作。MyBatis-P…...

小程序配置文件 —— 14 全局配置 - tabbar配置

全局配置 - tabBar配置 tabBar 字段&#xff1a;定义小程序顶部、底部 tab 栏&#xff0c;用以实现页面之间的快速切换&#xff1b;可以通过 tabBar 配置项指定 tab 栏的表现&#xff0c;以及 tab 切换时显示的对应页面&#xff1b; 在上面图中&#xff0c;标注了一些 tabBar …...

Redis-十大数据类型

Reids数据类型指的是value的类型&#xff0c;key都是字符串 redis-server:启动redis服务 redis-cli:进入redis交互式终端 常用的key的操作 redis的命令和参数不区分大小写 &#xff0c;key和value区分 1、查看当前库所有的key keys * 2、判断某个key是否存在 exists key 3、查…...

linux系统编程(七)管道和FIFO

1、管道 使用系统调用pipe可以创建一个新管道&#xff1a; #include <unistd.h> int pipe(int filedes[2]);成功的pipe调用会在数组filedes中返回两个打开的文件描述符&#xff0c;读取端为filedes[0]&#xff0c;写入端为filedes[1]。我们可以使用read/write系统调用在…...

【vLLM大模型TPS测试三部曲】

安装 pip install vllm模型自行下载 例如: https://modelscope.cn/models/jackle/Qwen2.5-Coder-32B-GPTQ-Int4/ 部署测试 export VLLM_MODELQwen2.5-Coder-32B-GPTQ-Int4 # 启动 python3 -m vllm.entrypoints.openai.api_server --model $VLLM_MODEL --deviceauto --enf…...

Elasticsearch:使用 Ollama 和 Go 开发 RAG 应用程序

作者&#xff1a;来自 Elastic Gustavo Llermaly 使用 Ollama 通过 Go 创建 RAG 应用程序来利用本地模型。 关于各种开放模型&#xff0c;有很多话要说。其中一些被称为 Mixtral 系列&#xff0c;各种规模都有&#xff0c;而一种可能不太为人所知的是 openbiollm&#xff0c;这…...