Kjører en Spring Boot-app med Maven vs en kjørbar krig / krukke

1. Introduksjon

I denne opplæringen vil vi utforske forskjellene mellom å starte en Spring Boot-nettapplikasjon via mvn spring-boot: run kommandoen og kjører den etter at den er samlet i en krukke / krigspakke via java -jar kommando.

La oss anta at du allerede er kjent med konfigurasjonen av Spring Boot ompakking mål. For mer informasjon om dette emnet, vennligst les Create a Fat Jar App with Spring Boot.

2. Spring Boot Maven Plugin

Når du skriver et Spring Boot-program, er Spring Boot Maven-plugin det anbefalte verktøyet for å bygge, teste og pakke koden vår.

Dette pluginet leveres med mange praktiske funksjoner, for eksempel:

  • det løser de riktige avhengighetsversjonene for oss
  • den kan pakke alle avhengighetene våre (inkludert en innebygd applikasjonsserver om nødvendig) i en enkelt, kjørbar fettkrukke / krig og vil også:
    • administrer klassesti-konfigurasjonen for oss, så vi kan hoppe over så lenge -cp alternativ i vår java -jar kommando
    • implementere en skikk ClassLoader for å finne og laste alle eksterne jar-biblioteker, som nå er nestet i pakken
    • finn automatisk hoved() metode og konfigurere den i manifestet, slik at vi ikke trenger å spesifisere hovedklassen i vår java -jar kommando

3. Kjøre koden med Maven i eksplodert form

Når vi jobber med en webapplikasjon, kan vi utnytte en annen veldig interessant funksjon av Spring Boot Maven-plugin: muligheten til å distribuere webapplikasjonen vår automatisk i en innebygd applikasjonsserver.

Vi trenger bare en avhengighet for å fortelle pluginet at vi vil bruke Tomcat til å kjøre koden vår:

 org.springframework.boot spring-boot-starter-web 

Nå, når du kjører mvn spring-boot: run kommandoen i prosjektets rotmappe, pluginet leser pom-konfigurasjonen og forstår at vi trenger en webapplikasjonsbeholder.

Gjennomføre mvn spring-boot: run kommandoen utløser nedlastingen av Apache Tomcat og initialiserer oppstarten av Tomcat.

La oss prøve det:

$ mvn spring-boot: run ... ... [INFO] ---------------------------------- ------ [INFO] Building spring-boot-ops 0.0.1-SNAPSHOT [INFO] --------------------------- ----- [krig] ------------------------------- [INFO] [INFO] >>> spring-boot-maven-plugin: 2.1.3.RELEASE: run (default-cli)> test-compile @ spring-boot-ops >>> Nedlasting fra sentralt: //repo.maven.apache.org/maven2/org /apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom Lastet ned fra sentralt: //repo.maven.apache.org/maven2/org/apache/tomcat/ legge inn / tomcat-embed-core / 9.0.16 / tomcat-embed-core-9.0.16.pom (1,8 kB ved 2,8 kB / s) ... ... [INFO] --- spring-boot-maven- plugin: 2.1.3.RELEASE: run (default-cli) @ spring-boot-ops --- ... ... 11: 33: 36.648 [main] INFO oacatalina.core.StandardService - Starter tjeneste [Tomcat] 11: 33: 36.649 [main] INFO oacatalina.core.StandardEngine - Starter Servlet-motor: [Apache Tomcat / 9.0.16] ... ... 11: 33: 36.952 [main] INFO oaccC [Tomcat]. [Localhost ]. [/] - Initialiserer våren em bedded WebApplicationContext ... ... 11: 33: 48.223 [main] INFO oacoyote.http11.Http11NioProtocol - Starter ProtocolHandler ["http-nio-8080"] 11: 33: 48.289 [main] INFO osbwetomcat.TomcatWebServer - Tomcat startet på port (er): 8080 (http) med kontekststi '' 11: 33: 48.292 [main] INFO org.baeldung.boot.Application - Started Application in 22.454 seconds (JVM running for 37.692)

Når loggen viser linjen som inneholder 'Started Application', er webapplikasjonen klar til å bli spurt via nettleseren på adressen // localhost: 8080 /

4. Kjøre koden som et frittstående pakket program

Når vi har bestått utviklingsfasen og ønsker å utvikle oss mot å bringe søknaden vår til produksjon, må vi pakke søknaden.

Dessverre, hvis vi jobber med en krukke pakken, den grunnleggende Maven pakke mål inkluderer ikke noen av de eksterne avhengighetene.

Dette betyr at vi bare kan bruke det som et bibliotek i et større prosjekt.

For å omgå denne begrensningen,vi trenger å utnytte Maven Spring Boot-plugin ompakking mål om å kjøre krukken / krigen vår som et frittstående program.

4.1. Konfigurasjon

Vanligvis trenger vi bare å konfigurere build-plugin:

  ... org.springframework.boot spring-boot-maven-plugin ... 

Men eksempelprosjektet vårt inneholder mer enn én hovedklasse, så vi må fortelle Java hvilken klasse vi skal kjøre, ved å enten konfigurere plugin:

 org.springframework.boot spring-boot-maven-plugin com.baeldung.webjar.WebjarsdemoApplication 

eller ved å stille inn startklasse eiendom:

 com.baeldung.webjar.WebjarsdemoApplication 

4.2. Kjører applikasjonen

Nå kan vi kjøre vårt eksemplar krig med to enkle kommandoer:

$ mvn clean package spring-boot: repackage $ java -jar target / spring-boot-ops.war

Mer informasjon om hvordan du kjører en jar-fil finner du i artikkelen Kjør JAR-applikasjon med kommandolinjeargumenter.

4.3. Inne i krigsfilen

For å forstå bedre hvordan kommandoen nevnt ovenfor kan kjøre et fullt serverprogram, kan vi ta en titt på vår spring-boot-ops.war.

Hvis vi pakker den ut og titter inn, finner vi de vanlige mistenkte:

  • META-INF, med den automatisk genererte MANIFEST.MF
  • WEB-INF / klasserinneholder våre kompilerte klasser
  • WEB-INF / lib, som har våre krigsavhengigheter og de innebygde Tomcat jar-filene

Det er ikke alt, da det er noen mapper som er spesifikke for konfigurasjonen av fettpakker:

  • WEB-INF / lib-forutsatt, som inneholder eksterne biblioteker som kreves når du kjører innebygd, men ikke nødvendig når du distribuerer
  • org / springframework / boot / loader, som har Spring Boot tilpasset klasselaster - dette biblioteket er ansvarlig for å laste inn våre eksterne avhengigheter og gjøre dem tilgjengelige i løpetid

4.4. Inne i krigsmanifestet

Som nevnt tidligere, finner Maven Spring Boot-plugin hovedklassen og genererer konfigurasjonen som trengs for å kjøre java kommando.

Resultatet MANIFEST.MF har noen ekstra linjer:

Startklasse: com.baeldung.webjar.WebjarsdemoApplication Hovedklasse: org.springframework.boot.loader.WarLauncher

Spesielt kan vi observere at den siste spesifiserer Spring Boot-klasse lasterstarter som skal brukes.

4.5. Inne i en krukkefil

På grunn av standard emballasjestrategi, vår krigsemballasje scenariet skiller seg ikke mye ut, enten vi bruker Spring Boot Maven Plugin eller ikke.

For å bedre forstå fordelene med pluginet, kan vi prøve å endre pom emballasje konfigurasjon til krukke og løp mvn ren pakke en gang til.

Vi kan nå se at fettkrukken vår er organisert litt annerledes enn vår forrige krigsfil:

  • Alle klassene og ressursmappene våre ligger nå under BOOT-INF / klasser
  • BOOT-INF / lib har alle eksterne biblioteker

Uten pluginet, er lib mappen ikke eksisterte, og alt innholdet i BOOT-INF / klasser ville være plassert i roten til pakken.

4.6. Inni i Jar Manifest

Også MANIFESTER.MF har endret seg med disse tilleggslinjene:

Spring-Boot-Classes: BOOT-INF / classes / Spring-Boot-Lib: BOOT-INF / lib / Spring-Boot-Version: 2.1.3.RELEASE Main-Class: org.springframework.boot.loader.JarLauncher

Spring-Boot-Classes og Spring-Boot-Lib er spesielt interessante, ettersom de forteller oss hvor klasselasteren skal finne klasser og eksterne biblioteker.

5. Hvordan velge

Når du analyserer verktøy, det er viktig å ta hensyn til formålet disse verktøyene er laget for. Ønsker vi å lette utviklingen eller sikre jevn distribusjon og bærbarhet? La oss se på fasene som er mest berørt av dette valget.

5.1. Utvikling

Som utviklere bruker vi ofte mesteparten av tiden vår på å kode uten å måtte bruke mye tid på å sette opp miljøet vårt for å kjøre koden lokalt. I enkle applikasjoner er det vanligvis ikke noe problem. Men for mer komplekse prosjekter, må vi kanskje sette miljøvariabler, starte servere og fylle ut databaser.

Å konfigurere det rette miljøet hver gang vi vil kjøre applikasjonen, vil være veldig upraktisk, spesielt hvis mer enn én tjeneste må kjøre samtidig.

Det er der du kjører koden med Maven hjelper oss. Vi har allerede sjekket ut hele kodebasen lokalt, slik at vi kan utnytte pom-konfigurasjon og ressursfiler. Vi kan angi miljøvariabler, gyte en database i minnet og til og med laste ned riktig serverversjon og distribuere applikasjonen vår med en kommando.

Selv i en kodebase med flere moduler, der hver modul trenger forskjellige variabler og serverversjoner, kan vi enkelt kjøre riktig miljø via Maven-profiler.

5.2. Produksjon

Jo mer vi beveger oss mot produksjon, jo mer skifter samtalen mot stabilitet og sikkerhet. Det er derfor vi ikke kan bruke prosessen som brukes for utviklingsmaskinen vår på en server med live kunder.

Å kjøre koden gjennom Maven på dette stadiet er dårlig praksis av flere grunner:

  • Først og fremst må vi installere Maven
  • Så, bare fordi vi trenger å kompilere koden, trenger vi hele Java Development Kit (JDK)
  • Deretter må vi kopiere kodebasen til serveren vår, og la all vår egen kode være i ren tekst
  • De mvn kommandoen må utføre alle faser i livssyklusen (finne kilder, kompilere og kjøre)
  • Takket være forrige punkt vil vi også kaste bort CPU og, i tilfelle en skyserver, penger
  • Maven gyter flere Java-prosesser, hver bruker minne (som standard bruker de samme minnemengde som foreldreprosessen)
  • Til slutt, hvis vi har flere servere å distribuere, gjentas alt ovenfor på hver enkelt

Dette er bare noen få grunner til det å sende applikasjonen som en pakke er mer praktisk for produksjon.

6. Konklusjon

I denne opplæringen undersøkte vi forskjellene mellom å kjøre koden vår via Maven og via java -jar kommando. Vi kjørte også en rask oversikt over noen praktiske saksscenarier.

Kildekoden som brukes i denne artikkelen er tilgjengelig på GitHub.


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