1. 概述

在使用 Maven 管理项目依赖时,随着项目演进,很容易积累一些实际上已经不再使用的依赖。这些“僵尸依赖”不仅增加了构建体积,还可能引入安全风险或版本冲突。

✅ **本文将介绍如何使用 Maven Dependency Plugin**,快速识别并清理项目中的未使用依赖。

这个插件是 Apache Maven 官方维护的成熟工具,集成简单,分析准确,适合在 CI/CD 流程中加入检查环节,避免技术债累积。

2. 项目准备

我们先构建一个包含两个依赖的简单项目:一个会被代码引用(slf4j-api),另一个不会被使用(commons-collections),用于演示检测效果。

<dependencies>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
</dependencies>

⚠️ 虽然 maven-dependency-plugin 通常无需显式声明即可使用,但为了版本可控,建议在 pom.xml 中明确指定版本:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.2</version>
        </plugin>
    </plugins>
</build>

这样可以避免不同环境使用插件版本不一致导致的行为差异,属于最佳实践。

3. 示例代码

接下来编写一段实际使用 slf4j-api 的代码,验证依赖是否真的被引用:

public Logger getLogger() {
    return LoggerFactory.getLogger(UnusedDependenciesExample.class);
}

📌 上述代码调用了 Slf4J 的 LoggerFactory,说明 slf4j-api有效依赖

❌ 而 commons-collections 在整个项目中没有任何导入或调用,属于典型的未使用依赖,应考虑移除。

4. 查找未使用依赖

执行以下命令触发依赖分析:

$ mvn dependency:analyze

输出结果如下:

[INFO] --- maven-dependency-plugin:3.1.1:analyze (default-cli) @ maven-unused-dependencies ---
[WARNING] Unused declared dependencies found:
[WARNING]    commons-collections:commons-collections:jar:3.2.2:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.225 s
[INFO] Finished at: 2020-04-01T16:10:25-04:00
[INFO] ------------------------------------------------------------------------

🔍 分析逻辑说明:

  • 插件通过扫描编译后的字节码(.class 文件)反向推导哪些依赖被实际引用。
  • 若某个 <dependency> 声明在 pom.xml 中,但其类未在代码中被加载或调用,则标记为 Unused declared dependencies
  • 输出中的警告明确指出了 commons-collections 是多余依赖。

5. 显式声明依赖为“已使用”

有些场景下,某些依赖虽然没有在代码中直接引用,但确实需要保留,例如:

  • ✅ 通过反射动态加载的类
  • ✅ SPI 机制加载的服务实现(如 JDBC 驱动)
  • ✅ 插件化架构中运行时注入的模块

此时若不干预,maven-dependency-plugin 会误报为“未使用”。我们可以通过配置 <usedDependencies> 手动豁免这些依赖:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <configuration>
        <usedDependencies>
            <dependency>commons-collections:commons-collections</dependency>
        </usedDependencies>
    </configuration>
</plugin>

📌 配置后再次运行 mvn dependency:analyze,该依赖将不再出现在警告列表中。

💡 小技巧:多个依赖可依次列出:

<usedDependencies>
    <dependency>groupId1:artifactId1</dependency>
    <dependency>groupId2:artifactId2</dependency>
</usedDependencies>

6. 总结

定期执行 mvn dependency:analyze 是保持项目整洁的有效手段:

  • ✅ 减少不必要的依赖,缩小构建产物体积
  • ✅ 降低依赖冲突和安全漏洞风险
  • ✅ 提升项目可维护性

⚠️ 踩坑提醒:该插件基于静态分析,对反射、字节码增强等动态行为支持有限,需结合业务逻辑合理配置豁免项。

📌 建议将此检查加入 CI 流程,例如通过脚本拦截构建失败,强制团队关注依赖健康度。

完整示例代码已托管至 GitHub:https://github.com/baeldung/tutorials/tree/master/maven-modules/maven-unused-dependencies


原始标题:Find Unused Maven Dependencies | Baeldung