paint-brush
如今,使用 Maven 的依赖分析器来清除未使用的依赖项是危险的建议经过@nfrankel
新歷史

如今,使用 Maven 的依赖分析器来清除未使用的依赖项是危险的建议

经过 Nicolas Fränkel
Nicolas Fränkel HackerNoon profile picture

Nicolas Fränkel

@nfrankel

Developer Advocate, eternal learner, author

4 分钟 read2025/03/13
Read on Terminal Reader
Read this story in a terminal
Print this story
tldt arrow
zh-flagZH
用繁體中文閱讀這個故事!
en-flagEN
Read this story in the original language, English!
es-flagES
Lee esta historia en Español!
ja-flagJA
この物語を日本語で読んでください!
qu-flagQU
Ñawinchay kay willakuyta en quechua!
ht-flagHT
Li istwa sa a an kreyòl ayisyen!
cs-flagCS
Přečtěte si tento příběh v češtině!
fa-AF-flagFA-AF
این داستان را به زبان دری بخوانید!
nl-flagNL
Lees dit verhaal in het Nederlands!
bg-flagBG
Прочетете тази история на български!
fi-flagFI
Lue tämä tarina suomeksi!
lv-flagLV
Izlasi šo stāstu latviešu valodā!
lt-flagLT
Skaitykite šią istoriją lietuvių kalba!
ZH

太長; 讀書

Maven 分析器的当前状态并没有为现代 Spring Boot 项目带来任何好处。
featured image - 如今,使用 Maven 的依赖分析器来清除未使用的依赖项是危险的建议
Nicolas Fränkel HackerNoon profile picture
Nicolas Fränkel

Nicolas Fränkel

@nfrankel

Developer Advocate, eternal learner, author


最近,我的好朋友 Richard Fichtner 建议使用mvn dependency:analyze命令来摆脱已声明但未使用的依赖项:


article preview
BLUESKY SOCIAL

Richard Fichtner 💻☕ (@richard.fichtner.dev)

There is another use case for mvn dependency:analyze It can show you the dependencies you use in your code but have not declared in your pom.xml. This works because you have a transitive dependency on your classpath. Either don't use the dependency or declare it.

虽然几年前这是一个好主意,但今天却是一个危险的建议。在这篇文章中,我想解释一下这个插件的作用以及为什么不应该在最简单的项目中使用它。

mvn dependency:analyze命令

Maven 使用插件架构;在上面的命令中,插件是maven-dependency-plugin 。一个插件承载着几个相关的目标。在这里,它是analyze


分析此项目的依赖项并确定哪些是:已使用且已声明;已使用且未声明;未使用且已声明。此目标旨在独立使用,因此它始终执行test-compile阶段 - 在参与构建生命周期时,请使用dependency:analyze-only目标。


默认情况下,使用maven-dependency-analyzer进行分析,由于它在字节码级别工作,因此存在局限性,但可以通过analyzer参数插入任何分析器。


--依赖项:分析


maven-dependency-analyzer是一个共享的 Maven 组件。它的描述相当详细:


分析项目中未声明或未使用的工件的依赖关系。

警告:由于分析是在字节码而不是源代码上进行的,因此有些情况无法检测到,包括常量、仅保留源代码的注释以及 Javadoc 中的链接。当这些是依赖项的唯一用途时,这可能会导致不正确的结果。


主要组件是ProjectDependencyAnalyzer ,它使用了ClassAnalyzerDependencyAnalyzer


–maven 依赖分析器


警告清楚地表明它在字节码级别起作用。特别是,它明确提到它不考虑源级注释。

Spring Boot 启动器

很久以前,我描述了如何设计自己的Spring Boot starter ,从那时起它就没有发生过太大的变化。如果你刚接触 Spring Boot starter,这里有一个总结。


SpringBoot 依赖于 AutoConfiguration 类。AutoConfiguration 类是常规配置类,它们对应用程序类有所贡献。您可以设置特定的激活条件,例如 Spring 属性的存在,但这些条件并非特定于自动配置。


这是一个非常简化的流程:


Spring Boot 中自动配置的简化序列图

Spring Boot 中自动配置的简化序列图


Spring Boot 自动附带的 JAR 是org.springframework.boot:spring-boot-autoconfigure 。你可以检查其META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports的内容:


 ... org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration


举个例子,下面是RestClientAutoConfiguration


 @AutoConfiguration(after = { HttpClientAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) //1 @ConditionalOnClass(RestTemplate.class) //2 @Conditional(NotReactiveWebApplicationCondition.class) //3 public class RestTemplateAutoConfiguration { // Class body }
  1. 设置自动配置类的顺序
  2. 如果RestTemplate类位于类路径上,则激活
  3. 如果我们不在响应式 Web 应用环境中则激活


请注意,无论RestTemplate类是否在类路径上,类加载器都可以很好地加载RestTemplateAutoConfiguration类!如上所示,Spring 充分利用了此机制。实际上,注释中配置的类的解析被推迟到显式访问它们为止。

maven-dependency-analyzer带入现代

提交者在 2007 年设计了该分析器:当时它的样子如下。Spring Boot 的推出时间较晚,为 2010 年。因此,该分析器未在注释中采用延迟类加载。请注意,现在情况仍然如此;该项目并没有得到太多的关注。


在 Spring Boot 项目中使用该插件时,您会得到很多误报。我在一个简单的 Spring Boot 项目中尝试了它,在 PostgreSQL 上使用 WebFlux 和 R2DBC。


以下是我运行mvn analyze:dependencies时输出的一小部分摘录:


 [WARNING] Unused declared dependencies found: [WARNING] org.springframework.boot:spring-boot-starter-data-r2dbc:jar:3.4.0:compile [WARNING] org.testcontainers:postgresql:jar:1.20.4:test [WARNING] org.testcontainers:r2dbc:jar:1.20.4:test


如果我删除任何这些依赖项,测试就不会运行。


要使分析器与 Spring Boot 项目一起工作,需要什么?让我们分析一下分析器。


分析器类图

分析器类图


该插件允许配置另一个分析器:


指定要使用的项目依赖项分析器(plexus 组件角色提示)。默认情况下,使用 maven-dependency-analyzer。要使用此功能,您必须为此插件声明一个包含分析器代码的依赖项。分析器必须具有声明的 Plexus 角色名称,您可以在此处指定角色名称。


  • 类型java.lang.String

  • : 2.2

  • 必填No

  • 用户属性analyzer

  • 默认值default


--依赖项:分析


我们可以创建一个整体的分析器,重复使用上面的内容,但添加一个特定于 Spring Boot 的分析器。

结论

Maven 分析器的当前状态对现代 Spring Boot 项目没有任何好处。现有代码可供配置甚至扩展。但是,我们需要嵌入大量 Spring Boot 逻辑。对于 Quarkus 和 Micronaut 项目,我们还需要专用代码。


我不知道这是否值得花费时间和精力。如果你认为值得,我希望这篇博文可以作为早期的分析。


进一步来说:





最初于 2025 年 3 月 9 日在A Java Geek上发布

L O A D I N G
. . . comments & more!

About Author

Nicolas Fränkel HackerNoon profile picture
Nicolas Fränkel@nfrankel
Developer Advocate, eternal learner, author

標籤

这篇文章刊登在...

Read on Terminal Reader
Read this story in a terminal
 Terminal
Read this story w/o Javascript
Read this story w/o Javascript
 Lite
Also published here
X REMOVE AD