Jaka jest różnica między dependencyManagement
i dependencies
? Widziałem dokumenty w witrynie Apache Maven. Wydaje się, że zależność zdefiniowana w parametrze dependencyManagement
może być używana w jego modułach potomnych bez określania wersji.
Na przykład:
Projekt nadrzędny (Pro-par) definiuje zależność w ramach dependencyManagement
:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8</version>
</dependency>
</dependencies>
</dependencyManagement>
Następnie w dziecku Pro-par mogę użyć junit:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
Zastanawiam się jednak, czy konieczne jest zdefiniowanie junit w pom-rodzicu? Dlaczego nie zdefiniować go bezpośrednio w potrzebnym module?
źródło
<dependencyManagement>
macierzystej POM. Uwzględnienie zależności w<dependencyManagement>
scentralizowanym zarządzaniu wersją, zakresem i wykluczeniami dla każdej zależności, jeśli i kiedy zdecydujesz się jej użyć. Przewodnik Mavena dotyczący zarządzania zależnościami zawiera wszystkie szczegóły.dependencyManagement
także kontroluje zależności przechodnie) jest prawdziwy tylko wtedy, gdy zależności są jawnie ustawione: stackoverflow.com/questions/28312975/…dependencies
sekcję w swoim pom pom. Zrobiliśmy to, aby wszystkie projekty potomne miały domyślnie pewne apache-commons i nie deklarowały ich przez cały czas.Modnie się spóźniłem na to pytanie, ale myślę, że warto odpowiedzieć jaśniej niż odpowiedź zaakceptowana (co jest poprawne, ale nie podkreśla faktycznej ważnej części, którą musisz wydedukować).
W macierzystej POM główna różnica między
<dependencies>
i<dependencyManagement>
jest następująca:Artefakty określone w
<dependencies>
sekcji ZAWSZE będą uwzględniane jako zależność modułów potomnych.Artefakty określone w
<dependencyManagement>
sekcji zostaną uwzględnione w module potomnym tylko wtedy, gdy zostały również określone w<dependencies>
sekcji samego modułu potomnego. Dlaczego dobrze pytasz? ponieważ określasz wersję i / lub zakres w rodzicu i możesz je pominąć, określając zależności w potomnym POM. Może to pomóc w użyciu zunifikowanych wersji dla zależności dla modułów potomnych, bez określania wersji w każdym module potomnym.źródło
<dependencyManagement>
over<dependencies>
w katalogu głównym.pom
? Dzieckopom
może być znacznie krótsze.Artifacts specified in the <dependencies> section will ALWAYS be included as a dependency of the child module(s)
, że są one również zawarte w rodzicu. Wydaje się, że nie można ustawić zależności dla dzieci, ale nie dla rodzica.Dokumentacja na stronie Maven jest straszne. Zadaniem dependenceManagement jest po prostu przeniesienie definicji zależności (wersja, wykluczenia itp.) Na pompę nadrzędną, a następnie w pompach podrzędnych wystarczy wstawić groupId i artefactId. To jest to (z wyjątkiem łączenia łańcuchów nadrzędnych i tym podobnych, ale to też nie jest bardzo skomplikowane - dependenceManagement wygrywa z zależnościami na poziomie nadrzędnym - ale jeśli masz pytania na temat tego lub importu, dokumentacja Maven jest nieco lepsza).
Po przeczytaniu wszystkich śmieci „a”, „b”, „c” na stronie Maven i zdezorientowaniu się, ponownie napisałem ich przykład. Więc jeśli miałeś 2 projekty (proj1 i proj2), które mają wspólną zależność (betaShared), możesz przenieść tę zależność do pom-nadrzędnej. W tym momencie możesz także przenieść dowolne inne zależności (alfa i charlie), ale tylko jeśli ma to sens dla twojego projektu. Tak więc dla sytuacji opisanej w poprzednich zdaniach, oto rozwiązanie z dependenceManagement w pom nadrzędnym:
źródło
To tak jak powiedziałeś;
dependencyManagement
służy do ściągnięcia wszystkich informacji o zależnościach do wspólnego pliku POM, co upraszcza odwołania w podrzędnym pliku POM.Staje się przydatny, gdy masz wiele atrybutów, których nie chcesz wpisywać w ramach wielu projektów potomnych.
Wreszcie
dependencyManagement
można go użyć do zdefiniowania standardowej wersji artefaktu do użycia w wielu projektach.źródło
Moim zdaniem jest jeszcze jedna rzecz, która nie jest wystarczająco podkreślona, a mianowicie niechciane dziedzictwo .
Oto przykład przyrostowy:
W moim
parent
pom deklaruję :Bum! Mam go w moich
Child A
,Child B
iChild C
modułów:version 18.0
w sposóbChild B
, jeśli chcę.Ale co, jeśli skończę nie potrzebując guawy
Child C
, ani w przyszłościChild D
iChild E
modułów?Nadal go odziedziczą, co jest niepożądane! Jest to tak samo jak zapach kodu Java God Object, w którym dziedziczysz pożyteczne bity z klasy i mnóstwo niechcianych rzeczy.
Tutaj
<dependencyManagement>
wchodzi w grę. Kiedy dodasz to do swojego pom pom, wszystkie moduły podrzędne przestają to widzieć . W ten sposób jesteś zmuszony wejść do każdego modułu, który tego potrzebuje, i zadeklarować go ponownie (Child A
iChild B
bez wersji).I oczywiście nie robisz tego
Child C
, a zatem twój moduł pozostaje szczupły.źródło
<dependencyManagement>
w pom pom, to domyślnie zależności nie zostaną odziedziczone w pom pom? Ponieważ w dokumencie doc: maven.apache.org/guides/introduction/… , wyjaśniając drugie użycie<dependencyManagement>
, wygląda na to, że zostanie domyślnie odziedziczone. W jednym wierszu mówią: „Kiedy maven jest uruchamiany w projekcie B, wersja 1.0 artefaktów a, b, cid będzie używana niezależnie od wersji określonej w ich pom”, nawet jeśli „b” nie jest używane w projekt BIstnieje kilka odpowiedzi, przedstawiające różnice pomiędzy
<depedencies>
i<dependencyManagement>
tagi z Maven.Jednak kilka punktów omówionych poniżej w zwięzły sposób:
<dependencyManagement>
pozwala na konsolidację wszystkich zależności (używanych na poziomie pom pom) używanych w różnych modułach - przejrzystość , centralne zarządzanie wersjami zależności<dependencyManagement>
pozwala na łatwą aktualizację / obniżenie zależności w zależności od potrzeb, w innym scenariuszu należy to wykonać na każdym poziomie pom dziecka - spójność<dependencies>
znaczniku są zawsze importowane, podczas gdy zależności podane<dependencyManagement>
w pom pom nadrzędnym zostaną zaimportowane tylko wtedy, gdy podrzędny pom ma odpowiedni wpis w swoim<dependencies>
znaczniku.źródło
Przepraszam za spóźnienie na imprezę.
Pozwól mi spróbować wyjaśnić różnicę za pomocą
mvn dependency:tree
poleceniaRozważ poniższy przykład
Parent POM - Mój projekt
Dziecko POM - moduł danych
Dziecko POM - moduł aplikacji (nie ma dodatkowej zależności, więc pozostawienie zależności jest puste)
Po uruchomieniu
mvn dependency:tree
polecenia otrzymujemy następujący wynikGoogle guava jest wymieniony jako zależność w każdym module (w tym nadrzędnym), podczas gdy wspólny apache jest wymieniony jako zależność tylko w module danych (nawet w module nadrzędnym)
źródło
Jeśli zależność została zdefiniowana w elemencie zależności najwyższego poziomu pom, projekt potomny nie musiał jawnie wyświetlać wersji zależności. jeśli projekt potomny zdefiniował wersję, zastąpiłby wersję wymienioną w sekcji dependenceManagement POM najwyższego poziomu. Oznacza to, że wersja dependenceManagement jest używana tylko wtedy, gdy dziecko nie deklaruje wersji bezpośrednio.
źródło
W macierzystej POM główna różnica między
<dependencies>
i<dependencyManagement>
jest następująca:Artefakty określone w
<dependencies>
sekcji ZAWSZE będą uwzględniane jako zależność modułów potomnych.Artefakty określone w sekcji zostaną uwzględnione w module potomnym tylko wtedy, gdy zostały również określone w sekcji samego modułu potomnego. Dlaczego dobrze pytasz? ponieważ określasz wersję i / lub zakres w rodzicu i możesz je pominąć, określając zależności w potomnym POM. Może to pomóc w użyciu zunifikowanych wersji dla zależności dla modułów potomnych, bez określania wersji w każdym module potomnym.
źródło
Według moich słów,
parent-project
pomagasz zapewnić 2 rodzaje zależności:<dependencies>
sekcji w tobieparent-project
są dziedziczone przez wszystkiechild-projects
child-projects
. Tak więc używasz<dependencyManagement>
sekcji, aby zadeklarować wszystkie zależności, których zamierzasz użyć w swojej innejchild-projects
. Najważniejsze jest to, że w tej sekcji definiujesz a<version>
, abyś nie musiał deklarować tego ponownie w swoimchild-project
.Z
<dependencyManagement>
mojego punktu widzenia (popraw mnie, jeśli się mylę) jest po prostu przydatny, pomagając w scentralizowaniu wersji swoich zależności. To jest coś w rodzaju funkcji pomocnika.źródło
W Eclipse jest jeszcze jedna funkcja
dependencyManagement
. Kiedydependencies
jest używane bez niego, nieuzasadnione zależności są zauważane w pliku pom. JeślidependencyManagement
jest używany, nierozwiązane zależności pozostają niezauważone w pliku pom, a błędy pojawiają się tylko w plikach Java. (import i takie ...)źródło
Różnicę między tymi dwoma najlepiej najlepiej przedstawić w niezbędnej i wystarczającej definicji elementu dependenceManagement dostępnego w dokumentach witryny Maven:
dependencyManagement
„Domyślne informacje o zależnościach dla projektów, które dziedziczą z tego. Zależności w tej sekcji nie są natychmiast usuwane. Zamiast tego, gdy POM pochodzący z tej deklaruje zależność opisaną przez pasujące groupId i artefactId, wersję i inne wartości z tej sekcji są używane dla tej zależności, jeśli nie zostały jeszcze określone. ” [ https://maven.apache.org/ref/3.6.1/maven-model/maven.html ]
Należy go przeczytać wraz z dodatkowymi informacjami dostępnymi na innej stronie:
„... minimalny zestaw informacji do dopasowania odwołania do zależności do sekcji dependenceManagement to tak naprawdę {groupId, artefactId, typ, klasyfikator}. W wielu przypadkach te zależności będą odnosić się do artefaktów jar bez klasyfikatora. To pozwala nam skrócić zestaw tożsamości na {groupId, artefactId}, ponieważ domyślnym polem typu jest jar, a domyślnym klasyfikatorem jest null. ” [ https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html ]
Tak więc wszystkie podelementy (zakres, wykluczenia itp.) Elementu zależności - inne niż groupId, artefactId, typ, klasyfikator, a nie tylko wersja - są dostępne do zablokowania / domyślnego w punkcie (a więc dziedziczone z od tego momentu) określasz zależność w ramach elementu dependenceElement. Jeśli określisz zależność z podelementami typu i klasyfikatora (zobacz pierwszą cytowaną stronę internetową, aby sprawdzić wszystkie podelementy) jako nie jar i odpowiednio null, potrzebujesz {groupId, artefactId, klasyfikator, typ} odwoływać się (rozwiązywać) tę zależność w dowolnym momencie spadku pochodzącego z elementu dependenceManagement. W przeciwnym razie wystarczy {groupId, artefactId}, jeśli nie zamierzasz zastępować wartości domyślnych dla klasyfikatora i typu (odpowiednio jar i null). Domyślne jest więc dobrym słowem kluczowym w tej definicji; dowolny podelement (-y) (inny niż groupId,
Tak więc każdy element zależności spoza dependenceManagement, czy to jako odwołanie do jakiegoś elementu dependenceManagement, czy jako samodzielny, jest natychmiast rozstrzygany (tj. Instalowany w lokalnym repozytorium i dostępny dla ścieżek klas).
źródło