Developer Advocate, eternal learner, author
Наскоро моят добър приятел Ричард Фихтнер посъветва използването на командата mvn dependency:analyze
, за да се отървете от декларирани, но неизползвани зависимости:
Въпреки че беше страхотна идея преди години, днес е опасен съвет. В тази публикация бих искал да обясня какво прави плъгинът и защо не трябва да го използвате освен в най-простите проекти.
mvn dependency:analyze
Maven използва плъгин архитектура; в горната команда плъгинът е maven-dependency-plugin . Плъгинът съдържа няколко свързани цели . Ето, това е analyze
.
Анализира зависимостите на този проект и определя кои са: използвани и декларирани; използвани и недекларирани; неизползвани и декларирани. Тази цел е предназначена да се използва самостоятелно, поради което винаги изпълнява фазата
test-compile
- вместо това използвайте целтаdependency:analyze-only
, когато участвате в жизнения цикъл на изграждане.
По подразбиране
maven-dependency-analyzer
се използва за извършване на анализа, с ограничения поради факта, че работи на ниво байт код, но всеки анализатор може да бъде включен чрез параметъраanalyzer
.
maven-dependency-analyzer
е споделен компонент на Maven. Описанието му е доста описателно:
Анализира зависимостите на проект за недекларирани или неизползвани артефакти.
Предупреждение : Тъй като анализът се извършва на байт кода , а не на източника, някои случаи не се откриват, включително константи, анотации със запазване само на източника и връзки в Javadoc. Това може да доведе до неправилни резултати, когато това са единствените употреби на зависимост.
Основният компонент е
ProjectDependencyAnalyzer
, който използваClassAnalyzer
иDependencyAnalyzer
.
Предупреждението ясно показва, че работи на ниво байт код . По-специално, той изрично споменава, че не взема предвид анотациите на ниво източник.
Описах как да проектирате свой собствен Spring Boot стартер преди много време и оттогава не се е променило много. Ако сте нов в начинаещите на Spring Boot, ето резюме.
SpringBoot разчита на класове AutoConfiguration. Класовете AutoConfiguration са обикновени класове за конфигурация, т.е. те допринасят за класовете на приложението. Можете да зададете конкретни критерии за активиране, като например наличието на свойство на Spring, но те не са специфични за автоматичната конфигурация.
Ето един много опростен поток:
Опростена диаграма на последователността на автоматичната конфигурация в Spring Boot
JAR, който автоматично идва с Spring Boot, е 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 }
RestTemplate
е на пътя на класа
Обърнете внимание, че програмата за зареждане на класове зарежда класа RestTemplateAutoConfiguration
съвсем добре, независимо дали класът RestTemplate
е на пътеката на класа или не! Spring използва този механизъм в най-голяма степен, както се вижда по-горе. Всъщност разделителната способност на класовете, конфигурирани в анотациите, се отлага, докато те не бъдат изрично достъпни.
maven-dependency-analyzer
в съвременната епохаCommitters проектираха анализатора през 2007 г.: ето как изглеждаше тогава. Spring Boot започна по-късно, през 2010 г. Поради тази причина анализаторът не взе отложено зареждане на клас в анотации. Имайте предвид, че това все още не е така; проектът не получава много любов.
Когато използвате плъгина в проект за Spring Boot, ще получите много фалшиви положителни резултати. Опитах го с прост Spring Boot проект, използвайки WebFlux и R2DBC на PostgreSQL.
Ето кратък откъс от изхода, когато стартирам 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? Нека анализираме анализатора.
Класова диаграма на анализатора
Плъгинът позволява конфигуриране на друг анализатор:
Посочете анализатора на зависимостта на проекта, който да използвате (подсказка за ролята на плексус компонент). По подразбиране се използва maven-dependency-analyzer. За да използвате това, трябва да декларирате зависимост за този плъгин, който съдържа кода за анализатора. Анализаторът трябва да има декларирано име на роля на Plexus и вие посочвате името на ролята тук.
Тип :
java.lang.String
От :
2.2
Задължително :
No
Потребителска собственост :
analyzer
По подразбиране :
default
Можем да създадем цялостен анализатор, който използва повторно горното, но добавя един специфичен за Spring Boot.
Текущото състояние на анализатора Maven не предлага никаква полза за съвременните проекти за Spring Boot. Съществуващият код е отворен за конфигуриране и дори разширение. Ще трябва обаче да вградим много логика на Spring Boot. За проектите Quarkus и Micronaut ще ни е необходим и специален код.
Не знам дали си струва времето и усилията. Ако смятате, че е, надявам се, че тази публикация в блога може да послужи като анализ на ранен етап.
За да отидете по-нататък:
Първоначално публикувано в A Java Geek на 9 март 2025 г