Multimodul Maven-applikation med Java-moduler

1. Oversigt

Java Platform Module System (JPMS) tilføjer mere pålidelighed, bedre adskillelse af bekymringer og stærkere indkapsling til Java-applikationer. Det er dog ikke et buildværktøj det mangler evnen til automatisk styring af projektafhængigheder.

Selvfølgelig kan vi undre os over, om vi kan brug veletablerede byggeværktøjer, som Maven eller Gradlei modulopbyggede applikationer.

Faktisk kan vi! I denne vejledning vi lærer, hvordan man opretter et multimodul Maven-program ved hjælp af Java-moduler.

2. Indkapsling af Maven-moduler i Java-moduler

Siden modularitet og afhængighedsstyring er ikke gensidigt eksklusive begreber i Java, Vi kan problemfrit integrere JPMS for eksempel med Maven og dermed udnytte det bedste fra begge verdener.

I et standard multimodul Maven-projekt tilføjer vi et eller flere underordnede Maven-moduler ved at placere dem under projektets rodmappe og erklære dem i den overordnede POM inden for afsnit.

Til gengæld redigerer vi hvert underordnet moduls POM og specificerer dets afhængigheder via standarden <groupId>, <artifactId> og <version> koordinater.

Det reaktor mekanisme i Maven - ansvarlig for håndtering af multimodulprojekter - sørger for at bygge hele projektet i den rigtige rækkefølge.

I dette tilfælde bruger vi grundlæggende den samme designmetode, men med en subtil, men alligevel grundlæggende variant: vi vikler hvert Maven-modul ind i et Java-modul ved at tilføje modulbeskrivelsesfilen til det, modul-info.java.

3. Parent Maven-modulet

For at demonstrere, hvordan modularitet og afhængighedsstyring fungerer godt sammen, bygger vi et grundlæggende demo-multimodul Maven-projekt, hvis funktionalitet indsnævres til bare at hente nogle domæneobjekter fra et persistenslag.

For at holde koden enkel, bruger vi en almindelig Kort som den underliggende datastruktur til lagring af domæneobjekter. Naturligvis kan vi let skifte længere nede ad en fuldt udviklet relationsdatabase.

Lad os starte med at definere det overordnede Maven-modul. For at opnå dette, lad os oprette en rodprojektmappe kaldet for eksempel multimodulemavenproject (men det kunne være noget andet), og tilføj forældren til det pom.xml fil:

com.baeldung.multimodulemavenproject multimodulemavenproject 1.0 pom multimodulemavenproject org.apache.maven.plugins maven-compiler-plugin 3.8.0 11 11 UTF-8 

Der er et par detaljer, der er værd at bemærke i definitionen af ​​den overordnede POM.

Først og fremmest, da vi bruger Java 11, vi har brug for mindst Maven 3.5.0 på vores system, da Maven understøtter Java 9 og højere fra den version og fremefter.

Og vi har også brug for mindst version 3.8.0 af Maven compiler plugin. Lad os derfor sørge for at kontrollere den nyeste version af pluginet på Maven Central.

4. Child Maven-modulerne

Bemærk, at indtil dette punkt, den overordnede POM erklærer ikke nogen underordnede moduler.

Da vores demo-projekt vil hente nogle domæneobjekter fra persistenslaget, opretter vi fire underordnede Maven-moduler:

  1. enhedsmodul: indeholder en simpel domæneklasse
  2. daomodule: holder den grænseflade, der kræves for at få adgang til persistenslaget (en grundlæggende DAO-kontrakt)
  3. userdaomodule: inkluderer en implementering af programmet daomoduleGrænseflade
  4. mainappmodule: projektets indgangssted

4.1. Det enhedsmodul Maven-modul

Lad os nu tilføje det første underordnede Maven-modul, som bare inkluderer en grundlæggende domæneklasse.

Lad os oprette under projektets rodmappe entitymodule / src / main / java / com / baeldung / entity katalogstruktur og tilføj en Bruger klasse:

offentlig klasse bruger {privat endelig strengnavn; // standard konstruktør / getter / toString}

Lad os derefter inkludere modulets pom.xml fil:

 com.baeldung.multimodulemavenproject multimodulemavenproject 1.0 com.baeldung.entitymodule entitymodule 1.0 jar entitymodule

Som vi kan se, er Enhed modulet har ingen afhængigheder af andre moduler, og det kræver heller ikke yderligere Maven-artefakter, da det kun inkluderer Bruger klasse.

Nu skal vi indkapsle Maven-modulet i et Java-modul. For at opnå dette skal vi blot placere følgende modulbeskrivelsesfil (modul-info.java) under entitymodule / src / main / java vejviser:

modul com.baeldung.entitymodule {eksporterer com.baeldung.entitymodule; }

Lad os endelig tilføje underordnet Maven-modul til den overordnede POM:

 enhedsmodul 

4.2. Det daomodule Maven-modul

Lad os oprette et nyt Maven-modul, der indeholder en simpel grænseflade. Dette er praktisk til at definere en abstrakt kontrakt til at hente generiske typer fra persistenslaget.

Faktisk er der en meget overbevisende grund til at placere denne grænseflade i et separat Java-modul. Ved at gøre dette har vi en abstrakt, stærkt afkoblet kontrakt, som er let at genbruge i forskellige sammenhænge. Kernen er dette en alternativ implementering af Dependency Inversion Principle, der giver et mere fleksibelt design.

Lad os derfor oprette daomodule / src / main / java / com / baeldung / dao katalogstruktur under projektets rodkatalog, og tilføj den Dao grænseflade:

offentlig grænseflade Dao {Valgfri findById (int id); Liste findAll (); }

Lad os nu definere modulets pom.xml fil:

 // forældrekoordinater com.baeldung.daomodule daomodule 1.0 jar daomodule

Det nye modul kræver heller ikke andre moduler eller artefakter, så vi pakker det bare ind i et Java-modul. Lad os oprette modulbeskrivelsen under daomodule / src / main / java vejviser:

modul com.baeldung.daomodule {eksporterer com.baeldung.daomodule; }

Lad os endelig tilføje modulet til den overordnede POM:

 entitymodule daomodule 

4.3. Det userdaomodule Maven-modul

Lad os derefter definere Maven-modulet, der indeholder en implementering af Dao interface.

Lad os oprette under projektets rodmappe userdaomodule / src / main / java / com / baeldung / userdao katalogstruktur, og tilføj følgende til det UserDao klasse:

offentlig klasse UserDao implementerer Dao {private final Map-brugere; // standardkonstruktør @ Override public Valgfri findById (int id) {return Optional.ofNullable (users.get (id)); } @ Override public List findAll () {returner ny ArrayList (users.values ​​()); }}

Kort sagt, den UserDao klasse giver en grundlæggende API, der giver os mulighed for at hente Bruger objekter fra persistenslaget.

For at holde tingene enkle brugte vi a Kort som baggrundsdatastruktur til vedvarende domæneobjekter. Det er selvfølgelig muligt at give en mere grundig implementering, der f.eks. Bruger Hibernates enhedsmanager.

Lad os nu definere Maven-modulets POM:

 // overordnede koordinater com.baeldung.userdaomodule userdaomodule 1.0 jar userdaomodule com.baeldung.entitymodule entitymodule 1.0 com.baeldung.daomodule daomodule 1.0 

I dette tilfælde er tingene lidt anderledes, som userdaomodule modul kræver entitymodule og daomodule moduler. Derfor tilføjede vi dem som afhængigheder i pom.xml fil.

Vi har stadig brug for at indkapsle dette Maven-modul i et Java-modul. Så lad os tilføje følgende modulbeskrivelse under userdaomodule / src / main / java vejviser:

modul com.baeldung.userdaomodule {kræver com.baeldung.entitymodule; kræver com.baeldung.daomodule; giver com.baeldung.daomodule.Dao com.baeldung.userdaomodule.UserDao; eksport com.baeldung.userdaomodule; } 

Endelig er vi nødt til at tilføje dette nye modul til den overordnede POM:

 entitymodule daomodule userdaomodule 

Fra et højt niveau er det let at se det det pom.xml filen og modulbeskrivelsen spiller forskellige roller. Alligevel supplerer de hinanden pænt.

Lad os sige, at vi skal opdatere versionerne af entitymodule og daomodule Maven artefakter. Vi kan nemt gøre dette uden at skulle ændre afhængighederne i modulbeskrivelsen. Maven tager sig af at inkludere de rigtige artefakter til os.

Tilsvarende kan vi ændre den serviceimplementering, som modulet giver ved at ændre “Giver..med” direktiv i modulbeskrivelsen.

Vi vinder meget, når vi bruger Maven- og Java-moduler sammen. Førstnævnte bringer funktionaliteten i automatisk, centraliseret afhængighedsstyring, mens sidstnævnte giver de iboende fordele ved modularitet.

4.4. Det mainappmodule Maven-modul

Derudover er vi nødt til at definere det Maven-modul, der indeholder projektets hovedklasse.

Som vi gjorde før, lad os oprette mainappmodule / src / main / java / mainapp katalogstruktur under rodmappen, og tilføj følgende til den Ansøgning klasse:

public class Application {public static void main (String [] args) {Map users = new HashMap (); users.put (1, ny bruger ("Julie")); users.put (2, ny bruger ("David")); Dao userDao = ny UserDao (brugere); userDao.findAll (). forEach (System.out :: println); }}

Det Ansøgning klassens hoved () metoden er ret enkel. For det første udfylder den en HashMap med et par Bruger genstande. Dernæst bruger den en UserDao eksempel for at hente dem fra Kort, og derefter viser det dem på konsollen.

Derudover skal vi også definere modulets pom.xml fil:

 // overordnede koordinater com.baeldung.mainappmodule mainappmodule 1.0 jar mainappmodule com.baeldung.entitymodule entitymodule 1.0 com.baeldung.daomodule daomodule 1.0 com.baeldung.userdaomodule userdaomodule 1.0 

Modulets afhængigheder er ret selvforklarende. Så vi skal bare placere modulet inde i et Java-modul. Derfor under mainappmodule / src / main / java katalogstruktur, lad os medtage modulbeskrivelsen:

modul com.baeldung.mainappmodule {kræver com.baeldung.entitypmodule; kræver com.baeldung.userdaopmodule; kræver com.baeldung.daopmodule; bruger com.baeldung.daopmodule.Dao; } 

Lad os endelig tilføje dette modul til den overordnede POM:

 entitymodule daomodule userdaomodule mainappmodule 

Med alle de underordnede Maven-moduler, der allerede er på plads, og pænt indkapslet i Java-moduler, ser projektets struktur sådan ud:

multimodulemavenproject (rodmappen) pom.xml | - entitymodule | - src | - main | - java module-info.java | - com | - baeldung | - enhed User.class pom.xml | - daomodule | - src | - main | - java module-info.java | - com | - baeldung | - dao Dao.class pom.xml | - userdaomodule | - src | - main | - java module-info.java | - com | - baeldung | - userdao UserDao.class pom.xml | - mainappmodule | - src | - main | - java module-info.java | - com | - baeldung | - mainapp Application.class pom.xml 

5. Kørsel af applikationen

Lad os endelig køre applikationen, enten inden i vores IDE eller fra en konsol.

Som vi kunne forvente, skulle vi se et par Bruger objekter, der udskrives til konsollen, når applikationen starter:

Bruger {name = Julie} Bruger {name = David} 

6. Konklusion

I denne vejledning lærte vi på en pragmatisk måde hvordan man får Maven og JPMS til at arbejde side om side i udviklingen af ​​et grundlæggende multimodul Maven-projekt, der bruger Java-moduler.

Som normalt er alle kodeeksempler vist i denne vejledning tilgængelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found