Podział dużego projektu w celu utworzenia wielomodułowego projektu Maven

23

Pracuję nad aplikacją Spring-MVC, w której używamy Maven do zarządzania zależnościami. Ponieważ projekt jest duży, zastanawiamy się nad podzieleniem go na kilka części. Miałem pewne wątpliwości, na które mam nadzieję uzyskam odpowiedzi tutaj.

Obecnie wdrażamy pojedynczy plik WAR jak ROOT.warna Apache tomcat na naszym serwerze. Ponieważ projekt jest duży, w aplikacji internetowej znajdują się części, takie jak Powiadomienia i poczta e-mail, Usługi stron trzecich, PUSH (Cometd), REST API itp. Obecnie wszystkie z nich są ze sobą powiązane i zależą od siebie. Na przykład Notificationobiekt zależy również od Personobiektu, ponieważ powiadomienia są dostosowane do użytkowników.

Głównym celem podziału dużego projektu jest możliwość pracy nad poszczególnymi modułami, poprawek błędów, dodawania funkcji, testowania itp. A gdy jest to spełnione, tylko ten moduł można wymienić na serwerze zamiast całej aplikacji. czy to możliwe?

Jak już wspomniałem wcześniej, istnieją zależności i odwzorowania między obiektami. W jaki sposób będą one zarządzane w różnych podmodułach, czy tylko instrukcje importu zmienią się i będą obejmować inne projekty?

Jak powiedziałem, intencją jest praca nad poszczególnymi modułami i możliwość ich wdrożenia (najlepiej na gorąco). Obecnie mamy tylko jeden plik WAR jako ROOT.war. Czy podział spowoduje utworzenie wielu plików wojen, które następnie będą nazywane URL-em domain-name.com/module_name/some_mapping?

Obecnie sprawdzam dokumentację, ale jest to główny cel, który chcemy osiągnąć dzięki modułowi wielostanowiskowemu dostarczonemu przez Maven i zainteresowanemu wiedzieć, czy jest to wykonalne. Jeśli potrzebujesz więcej informacji, daj mi znać.

Obecnie używam nadrzędnej POM od wiosny w następujący sposób:

<parent>
    <groupId>io.spring.platform</groupId>
    <artifactId>platform-bom</artifactId>
    <version>1.1.3.RELEASE</version>
    <relativePath />
</parent>
Jesteśmy Borg
źródło
1
Pozostawiam to innym do odpowiedzi. Pomysł jest bardzo solidny. Możesz zacząć od nadrzędnej POM z dependenceManagement i słoikiem dla DAO, takich jak Person. Bardzo podstawowa biblioteka. I tak dalej. Oczywiście nie ma cyklicznych zależności.
Joop Eggen,

Odpowiedzi:

20

Czy to możliwe ?

Tak na pewno. W przeszłości miałem kilka takich projektów, tutaj mam nadzieję, że zaczniesz.

Istnieją dwie główne cechy Maven, których użyjesz do splotu rzeczy:

Dziel i rządź

Będziesz musiał podzielić swoje projekty na wiele niezależnych projektów. Przez niezależne rozumiem tutaj, że wszystkie odniesienia do kodu poza projektem są dokonywane przez zależności w Maven, a nie przez bezpośrednie połączenie drzewa źródłowego.

W zależności od stanu twojego drzewa źródłowego może to stanowić dużo pracy. To powiedziawszy, nie robisz tego po to, by dotrzeć do Maven, ale raczej po to, aby uporządkować i oczyścić bazę kodu. Pomyśl o tym jak o narzędziach, o wiele łatwiej znaleźć tutaj:

Niezła szopa na narzędzia

niż tutaj:

Niezbyt ładna szopa na narzędzia

Maven w dużej mierze opiera się na konwencji, więc im lepiej zorganizujesz swoje rzeczy, tym bardziej Maven może ci pomóc. To powiedziawszy, może być konieczna ponowna organizacja w celu lepszego dopasowania do jej własnej konwencji, a jeśli muszę tu dać jedną radę, to, że O wiele łatwiej jest zmienić swoje rzeczy, aby pasowały do ​​konwencji Mavena, niż jest to próba skonfigurowania Maven do zrozum swoją konwencję.

Jeśli te projekty mogłyby być użyteczne poza główną aplikacją, mogłyby żyć jako prawdziwie niezależne biblioteki i uwzględniać choćby zależności od maven. Powinny one mieszkać we własnym repozytorium (nie w drzewie źródeł aplikacji) i nie powinny zależeć od żadnej części głównej aplikacji.

Najważniejsze części aplikacji, po podzieleniu na projekty, można łączyć jako moduły. Zazwyczaj są one umieszczane jako podfolder głównego folderu źródłowego aplikacji.

Również twoja nadrzędna POM dla Twojej aplikacji będzie zawierać deklarację modułu. Umieścisz tam również wszystkie typowe zależności dla Twojej aplikacji, a także zadeklarujesz większość wtyczek kompilacji i ich konfiguracji. Tutaj również gorąco polecam umieszczenie grupy właściwości dla takich rzeczy, jak wersja aplikacji, którą można ponownie wykorzystać w modułach. Znacznie łatwiej jest zarządzać, gdy wszystko ma tę samą wersję, a posiadanie wersji w jednym miejscu sprawia, że ​​to po prostu działa.

Obróbka

Jeśli jesteś zespołem większym niż 1, zdecydowanie zalecam zainstalowanie repozytorium dla zależności Maven. Spójrz na Artifactory , Nexus lub Archiva . Możesz skonfigurować plik POM, aby instalował się na tych plikach bezpośrednio, więc po uruchomieniu nie powinno to stanowić dużego obciążenia, ale pozwoli zaoszczędzić Twojemu zespołowi wiele czasu na rozwiązywanie zależności z właściwym słoikiem we właściwym miejscu.

Na temat oprzyrządowania kolejnym logicznym krokiem jest tutaj system ciągłej integracji ( Jenkins , jest ich znacznie więcej). Poradzi sobie z budowaniem źródła, uruchamianiem testów i przepychaniem do artefaktów, z tym wszystkim, co musisz zrobić, to pracować z kodem, a reszta po prostu działa.

Ponieważ pakujesz swoją aplikację, ponieważ maven wojenny może poradzić sobie z budowaniem wojny i umieścić wszystkie zależności we właściwych miejscach bez konieczności łączenia plików jar lub innych podobnych działań, więc nie martw się.

Przykład

Mógłbym tu trwać znacznie dłużej, ale nic nie jest dobrym przykładem. Spójrz na github pod kątem projektów o podobnej wielkości i zobacz, jak zbudowali swoje pliki pom i hierarchie folderów. Spójrz na więcej niż jeden, niektóre będą pasowały do konfiguracji lepiej niż inni, nikt naprawdę wcielić się prawdy, ale należy znaleźć wystarczająco paliwa myśli o tym, jak zrobić to.

Weźmy na przykład Jenkinsa :

Widać, że ich macierzysty POM jest dość obszerny.

Używają modułów, jak widać w tej sekcji:

<modules>
    <module>core</module>
    <module>war</module>
    <module>test</module>
    <module>cli</module>
</modules>

I każdy moduł odpowiada podfolderowi o tej samej nazwie, który również zawiera POM. Możesz zagnieździć tyle, ile chcesz, ale trzymaj to w granicach rozsądku;).

Zacznij od małego

Jeśli nigdy nie korzystałeś z Maven, sugerowałbym, że nie zaczynaj od modułów od razu. Pośpiesz się, zacznij od, powiedzmy, jednej z prostszych bibliotek, którą możesz mieć, i spraw, by był to projekt maven. Następnie uczyń swoją główną aplikację prostym projektem maven. Po zakończeniu pracy zacznij dodawać proste zależności, a następnie podziel pierwszy moduł i tak dalej.

Maven to świetne narzędzie, ale może też być bardzo bolesne w szyi, szczególnie gdy nie wszystko idzie po twojej myśli. Począwszy od całego whammy za pierwszym razem jest receptą na katastrofę (było dla mnie!).

Jeśli coś jest trochę dziwne, zawsze możesz użyć mvn help:effective-pompolecenia, aby zobaczyć, co Maven rzeczywiście zrozumiał.

wtyczki

Z twojego komentarza rozumiem lepiej, co chcesz osiągnąć. W tym przypadku wybrałbym podejście do wtyczek. Utwórz projekt, który udostępnia interfejs API punktów rozszerzenia, w których chcesz odizolować pracę. Następnie możesz użyć tego jako zależności w nowym projekcie, który go zaimplementuje. W swojej głównej aplikacji po prostu dodaj odpowiednie zależności dla tych implementacji (tym razem nie wykorzystując modułów maven) i powinieneś już iść. Ostatecznie główny projekt aplikacji nie będzie zawierał prawie żadnego kodu źródłowego, wszystko wykonywane w projektach zewnętrznych i ładowane przez zależności.

Będziesz musiał jednak ponownie wdrożyć całą aplikację z tym podejściem, niezależnie od tego, czy rdzeń się zmienił, czy nie, ponieważ wojna jest zbudowana statycznie z zależności, zmiana jednego z nich oznacza przebudowanie całości. Brzmi najgorzej, niż jest w rzeczywistości, w rzeczywistości tylko nowe zmiany zostaną zbudowane, reszta będzie w zasadzie kopią poprzednich słoików. Ale ponieważ wszystko znajduje się w pliku wojny, trzeba będzie go odbudować, a serwer będzie musiał zostać zatrzymany i ponownie uruchomiony.

Jeśli chcesz iść dalej, nieco bardziej skomplikuj, choć nie jest to niemożliwe. Polecam przyjrzeć się OSGI, Apache Felix może zacząć, choć są też inne implementacje. Pozwoli ci to wziąć zewnętrzny słoik i przekształcić je we właściwe wtyczki. Zyskasz znacznie większą kontrolę nad cyklem życia komponentów wykonawczych, otwierając drzwi do dynamicznych przeładowań i aktualizacji. Będzie to jednak wymagało poważnych zmian w twoim rdzeniu, więc prawdopodobnie nie jest to dobry punkt wyjścia. Jeśli jednak masz projekt, który jest dobrze oddzielony i wszystkie części są odizolowane tak, jak chcesz, może to być naturalny następny krok, jeśli uruchomienie i zatrzymanie aplikacji podczas aktualizacji jest poważnym problemem.

Podstawowa różnica między modułami a zależnościami jest taka:

  • Moduły będą znajdować się w tym samym drzewie źródłowym co główna aplikacja, najlepiej jako podfoldery.
  • Zależności mogą być wszędzie.

Biblię znajdziesz tutaj .

Mam nadzięję, że to pomogło, powodzenia.

Newtopian
źródło
W rzeczywistości łączenie modułów przez maven zamiast z drzewa źródeł rozwiązało wiele pytań, które miałem. Czy możesz mi powiedzieć o wdrożeniu takiego projektu. Jednym z innych rozważanych powodów jest to, że programiści mogą pracować nad wymaganym modułem i wprowadzać zmiany w czasie rzeczywistym. Jedną rzeczą, której chcemy uniknąć, jest zatrzymanie serwera aplikacji i rozpoczęcie od nowa, inne niż dla modułu podstawowego. Jako 2 moduły, o których myślę, będzie zawierał kod, który często się zmienia. Używamy tomcat jako serwera aplikacji, równoważonego obciążeniem przez Apache. Dziękuję Ci.
Jesteśmy Borg
Moduły Maven często znajdują się w tym samym drzewie źródłowym co główna aplikacja. Używanie modułów maven poza drzewem źródłowym jest w rzeczywistości bardziej skomplikowane, niż jest naprawdę warte. Jeśli hostujesz projekty poza drzewem źródłowym, wybierz normalne niezależne projekty i użyj normalnych zależności.
Newtopian
Myślę, że pójdziemy dodawać części naszego projektu bezpośrednio jako zależności Maven. W ten sposób możemy bezpośrednio pracować nad częściami projektu. Mam tylko jedno pytanie: jeśli dodamy jeden z podprojektów jako zależność w POM.xml, powiedzmy w wersji 2.0.0, a następnie z pewnymi zmianami wypychamy 2.0.1 modułu do sonatype, w jaki sposób możemy powiedz bezpośrednio modułowi głównemu, aby wybrał wersję 2.0.1, wystarczy zmienić POM.xml w pliku ROOT.war i usunąć katalog ROOT. Głównym celem nie jest zatrzymanie serwera. Dziękuję Ci.
Jesteśmy Borg
plik pom.xml nie ma żadnego znaczenia po utworzeniu wojny, tzn. Tomcat (lub inny używany kontener) nie korzysta z tego pliku. Plik jest używany przez Maven do utworzenia nowego pliku wojny, który z kolei będzie musiał zostać wdrożony na serwerze. Tak więc cykl polega na pracy nad kodem, utwórz plik jar, zaktualizuj wersję w POM wojennej, utwórz plik wojenny, zaktualizuj serwer o nowy plik wojenny. Niektóre serwery będą obsługiwać ponowne wdrażanie na gorąco, jednak ogólnie oznaczałoby to wyłączenie aplikacji na kilka sekund.
Newtopian