Onlangs adviseerde mijn goede vriend Richard Fichtner om de mvn dependency:analyze
te gebruiken om gedeclareerde maar ongebruikte afhankelijkheden te verwijderen:
Hoewel het jaren geleden een geweldig idee was, is het vandaag de dag gevaarlijk advies. In dit bericht wil ik uitleggen wat de plugin doet en waarom je hem niet moet gebruiken, maar alleen in de meest eenvoudige projecten.
De opdracht mvn dependency:analyze
Maven gebruikt een plugin-architectuur; in de bovenstaande opdracht is de plugin maven-dependency-plugin . Een plugin host verschillende gerelateerde doelen . Hier is het analyze
.
Analyseert de afhankelijkheden van dit project en bepaalt welke: gebruikt en gedeclareerd; gebruikt en niet-gedeclareerd; ongebruikt en gedeclareerd zijn. Dit doel is bedoeld om stand-alone te worden gebruikt, dus het voert altijd de
test-compile
fase uit - gebruik in plaats daarvan hetdependency:analyze-only
doel wanneer u deelneemt aan de build lifecycle.
Standaard wordt
maven-dependency-analyzer
gebruikt om de analyse uit te voeren, met beperkingen vanwege het feit dat het op bytecodeniveau werkt. U kunt echter elke analyzer aansluiten viaanalyzer
.
maven-dependency-analyzer
is een gedeelde Maven-component. De beschrijving is vrij beschrijvend:
Analyseert de afhankelijkheden van een project voor niet-aangegeven of ongebruikte artefacten.
Waarschuwing : Omdat de analyse wordt uitgevoerd op de bytecode in plaats van de bron, worden sommige gevallen niet gedetecteerd, waaronder constanten, annotaties met alleen bronbehoud en links in Javadoc. Dit kan leiden tot onjuiste resultaten wanneer dit de enige toepassingen van een afhankelijkheid zijn.
Het hoofdonderdeel is
ProjectDependencyAnalyzer
, datClassAnalyzer
enDependencyAnalyzer
gebruikt.
De waarschuwing laat duidelijk zien dat het op bytecode -niveau werkt. In het bijzonder wordt expliciet vermeld dat het geen rekening houdt met annotaties op bronniveau.
Spring Boot-starters
Ik heb lang geleden beschreven hoe je je eigen Spring Boot starter kunt ontwerpen, en sindsdien is er niet veel veranderd. Als je nieuw bent met Spring Boot starters, hier is een samenvatting.
SpringBoot is afhankelijk van AutoConfiguration-klassen. AutoConfiguration-klassen zijn reguliere configuratieklassen, d.w.z. ze dragen bij aan de toepassingsklassen. U kunt specifieke activeringscriteria instellen, zoals de aanwezigheid van een Spring-eigenschap, maar deze zijn niet specifiek voor autoconfiguratie.
Hier is een zeer vereenvoudigde stroom:
De JAR die automatisch met Spring Boot wordt meegeleverd is org.springframework.boot:spring-boot-autoconfigure
. U kunt de inhoud van META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
controleren:
... 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
Als voorbeeld is hier de RestClientAutoConfiguration
:
@AutoConfiguration(after = { HttpClientAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) //1 @ConditionalOnClass(RestTemplate.class) //2 @Conditional(NotReactiveWebApplicationCondition.class) //3 public class RestTemplateAutoConfiguration { // Class body }
- De volgorde van autoconfiguratieklassen instellen
- Activeren als de
RestTemplate
-klasse zich op het classpath bevindt - Activeren als we ons niet in een reactieve web-app-context bevinden
Let op dat de class loader de RestTemplateAutoConfiguration
-klasse prima laadt, ongeacht of de RestTemplate
-klasse zich op het classpath bevindt of niet! Spring maakt optimaal gebruik van dit mechanisme, zoals hierboven te zien is. In feite wordt de resolutie van klassen die in annotaties zijn geconfigureerd, uitgesteld totdat ze expliciet worden benaderd.
De maven-dependency-analyzer
naar het moderne tijdperk brengen
Committers ontwierpen de analyzer in 2007: zo zag het er toen uit. Spring Boot startte later, in 2010. Om die reden nam de analyzer geen uitgestelde klasselading op in annotaties. Let wel, dit is nog steeds niet het geval; het project krijgt niet veel liefde.
Wanneer u de plugin gebruikt op een Spring Boot-project, krijgt u veel false positives. Ik heb het geprobeerd met een eenvoudig Spring Boot-project, met WebFlux en R2DBC op PostgreSQL.
Hier is een klein fragment van de uitvoer wanneer ik mvn analyze:dependencies
uitvoer:
[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
Als ik een van deze afhankelijkheden verwijder, worden de tests niet uitgevoerd.
Wat zou er nodig zijn om de analyzer te laten werken met Spring Boot-projecten? Laten we de analyzer analyseren.
Met de plugin kunt u een andere analyzer configureren:
Geef de project dependency analyzer op die u wilt gebruiken (plexus component role-hint). Standaard wordt maven-dependency-analyzer gebruikt. Om dit te gebruiken, moet u een dependency voor deze plugin declareren die de code voor de analyzer bevat. De analyzer moet een gedeclareerde Plexus-rolnaam hebben en u geeft hier de rolnaam op.
Type :
java.lang.String
Sinds :
2.2
Verplicht :
No
Gebruikerseigenschap :
analyzer
Standaard :
default
We kunnen een algemene analysator maken die het bovenstaande hergebruikt, maar er een specifieke aan Spring Boot toevoegt.
Conclusie
De huidige status van de Maven-analysator biedt geen enkel voordeel voor moderne Spring Boot-projecten. De bestaande code is open voor configuratie en zelfs uitbreiding. We zouden echter veel Spring Boot-logica moeten inbedden. Voor Quarkus- en Micronaut-projecten zouden we ook speciale code nodig hebben.
Ik weet niet of het de tijd en moeite waard is. Als u dat vindt, hoop ik dat deze blogpost kan dienen als een vroege analyse.
Om verder te gaan:
- afhankelijkheid:analyseren
- Maven-afhankelijkheidsanalysator
- Ontwerp je eigen Spring Boot starter – deel 1
- Ontwerp je eigen Spring Boot starter – deel 2
Oorspronkelijk gepubliceerd op A Java Geek op 9 maart 2025