Tanke JAR-ove s proljetnim čizmama

1. Uvod

U ovom uputstvu ćemo pogledati kako izgraditi projekt Spring Boot u tanku JAR datoteku, koristeći opruga-čizma-tanki-lansir projekt.

Spring Boot poznat je po svojim "debelim" implementacijama JAR-a, gdje jedan izvršni artefakt sadrži i aplikacijski kôd i sve njegove ovisnosti.

Čizma se također široko koristi za razvoj mikroservisa. To se ponekad može sukobiti s pristupom "masnog JAR-a", jer ponavljanje istih ovisnosti u mnogim artefaktima može postati važan gubitak resursa.

2. Preduvjeti

Prije svega, naravno, potreban nam je projekt Spring Boot. U ovom ćemo članku pogledati Maven gradnje i Gradle gradnje u njihovim najčešćim konfiguracijama.

Nemoguće je pokriti sve sustave gradnje i konfiguracije izrade, ali, nadamo se, pregledat ćemo dovoljno općih načela da biste ih mogli primijeniti na svoje specifične postavke.

2.1. Maven projekti

U projektu pokretanja izgrađenom s Mavenom, trebali bismo imati dodatak Spring Boot Maven konfiguriran u našem projektu pom.xml datoteka, roditelj ili jedan od predaka:

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

O verziji ovisnosti Spring Boota obično se odlučuje upotrebom BOM-a ili nasljeđivanjem od nadređenog POM-a kao u našem referentnom projektu:

 org.springframework.boot spring-boot-starter-parent 2.2.2.Opusti 

2.2. Projekti Gradle

U projektu pokretanja izgrađenom pomoću Gradlea, imat ćemo dodatak Boot Gradle:

buildscript {ext {springBootPlugin = 'org.springframework.boot: spring-boot-gradle-plugin' springBootVersion = '2.2.2.RELEASE'} spremišta {mavenCentral ()} zavisnosti {classpath ("$ {springBootPlugin}: $ {springBootVersion } ")}} // dodani dodatak za primjenu: 'org.springframework.boot' primijeni dodatak: 'io.spring.dependency-management' springBoot {mainClassName = 'com.baeldung.DemoApplication'}

Imajte na umu da ćemo u ovom članku razmatrati samo projekte Boot 2.x i novije verzije. Tanki pokretač također podržava ranije verzije, ali zahtijeva malo drugačiju Gradle konfiguraciju koju izostavljamo zbog jednostavnosti. Molimo pogledajte detalje na početnoj stranici projekta.

3. Kako stvoriti tanki JAR?

Tanki pokretač Spring Boot mala je knjižnica koja čita ovisnosti artefakta iz datoteke upakirane u samu arhivu, preuzima ih iz spremišta Maven i na kraju pokreće glavnu klasu aplikacije.

Tako, kada gradimo projekt s knjižnicom, dobivamo JAR datoteku s našim kodom, datoteku koja nabraja njegove ovisnosti i glavnu klasu iz knjižnice koja izvodi gore navedene zadatke.

Naravno, stvari su malo nijansirane od našeg pojednostavljenog objašnjenja; o nekim ćemo temama detaljno razgovarati kasnije u članku.

4. Osnovna upotreba

Pogledajmo sada kako napraviti "tanki" JAR iz naše redovite Spring Boot aplikacije.

Pokrenut ćemo aplikaciju na uobičajeni način java -jar, s neobaveznim dodatnim argumentima naredbenog retka koji kontroliraju tanki pokretač. Nekoliko ćemo ih vidjeti u sljedećim odjeljcima; početna stranica projekta sadrži cjelovit popis.

4.1. Maven projekti

U projektu Maven moramo izmijeniti deklaraciju dodatka za pokretanje (vidi odjeljak 2.1) kako bismo uključili ovisnost o prilagođenom "tankom" izgledu:

 org.springframework.boot spring-boot-maven-plugin org.springframework.boot.experimental spring-boot-thin-layout 1.0.11.OSLOBOĐENJE 

Pokretač će čitati ovisnosti s pom.xml datoteku koju Maven pohranjuje u generirani JAR u META-INF / maven imenik.

Izgradit ćemo izvedbu kao i obično, npr. S mvn instalirati.

Ako želimo biti u stanju proizvoditi i tanke i masne građe (na primjer u projektu s više modula), možemo prijaviti prilagođeni izgled u namjenskom Maven profilu.

4.2. Maven i ovisnosti: tanka.svojstva

Također možemo Maven generirati tanka.svojstva datoteka uz pom.xml. U tom će slučaju datoteka sadržavati cjelovit popis ovisnosti, uključujući prijelazne, a pokretač će joj dati prednost nad pom.xml.

Mojo (dodatak) za to je spring-boot-thin-maven-plugin: svojstva, i prema zadanim postavkama daje tanka.svojstva uloži u src / main / resources / META-INF, ali možemo odrediti njegovo mjesto pomoću tanak.izlaz svojstvo:

$ mvn org.springframework.boot.experimental: spring-boot-thin-maven-plugin: svojstva -Dthin.output =.

Imajte na umu da izlazni direktorij mora postojati da bi cilj uspio, čak i ako smo zadržali zadani.

4.3. Projekti Gradle

U projekt Gradle, umjesto toga, dodajemo namjenski dodatak:

buildscript {ext {// ... thinPlugin = 'org.springframework.boot.experimental: spring-boot-thin-gradle-plugin' thinVersion = '1.0.11.RELEASE'} // ... ovisnosti {//. .. classpath ("$ {thinPlugin}: $ {thinVersion}")}} // elided primijeniti dodatak: 'maven' primijeniti dodatak: 'org.springframework.boot.experimental.thin-launcher'

Da bismo dobili tanku građu, reći ćemo Gradleu da izvrši tankiJar zadatak:

~ / projects / baeldung / spring-boot-gradle $ ./gradlew thinJar

4.4. Gradle i ovisnosti: pom.xml

U primjeru koda u prethodnom odjeljku, dodali smo dodatak Maven uz tanki pokretač (kao i dodatke za pokretanje i upravljanje ovisnostima koje smo već vidjeli u odjeljku Preduvjeti).

To je zato što će, baš kao i u slučaju Maven koji smo vidjeli ranije, artefakt sadržavati i koristiti ga pom.xml datoteka koja nabraja ovisnosti aplikacije. The pom.xml datoteku generira zadatak nazvan thinPom, što je implicitna ovisnost bilo kojeg jar zadatka.

Generirano možemo prilagoditi pom.xml datoteka s namjenskim zadatkom. Ovdje ćemo samo automatski ponoviti ono što tanki dodatak već radi:

zadatak createPom {def basePath = 'build / resources / main / META-INF / maven' doLast {pom {withXml (dependencyManagement.pomConfigurer)} .writeTo ("$ {basePath} / $ {project.group} / $ {project. ime} /pom.xml ")}}

Da se poslužimo našim običajem pom.xml datoteku, dodamo gornji zadatak ovisnostima jar zadatka:

bootJar.dependsOn = [createPom]

4.5. Gradle i ovisnosti: tanka.svojstva

Gradle također može generirati tanka.svojstva datoteka, a ne pom.xml, kao što smo to ranije radili s Mavenom.

Zadatak koji generira tanka.svojstva datoteka se zove thinProperties, i ne koristi se prema zadanim postavkama. Možemo ga dodati kao ovisnost zadatka jar:

bootJar.dependsOn = [tanke osobine]

5. Pohranjivanje ovisnosti

Cijela poanta tankih teglica je izbjegavanje povezivanja ovisnosti s aplikacijom. Međutim, ovisnosti ne magično nestaju, one se jednostavno pohranjuju negdje drugdje.

Tanki pokretač posebno koristi Maven infrastrukturu za rješavanje ovisnosti, pa:

  1. provjerava lokalno spremište Maven, koje po defaultu leži ~ / .m2 / spremište ali se može premjestiti drugdje;
  2. zatim preuzima ovisnosti koje nedostaju iz Maven Central (ili bilo kojeg drugog konfiguriranog spremišta);
  3. napokon, sprema ih u lokalno spremište, tako da ih neće morati ponovno preuzimati sljedeći put kad pokrenemo aplikaciju.

Naravno, faza preuzimanja je polagani i skloni pogreškama dio procesa, jer zahtijeva pristup Maven Central-u putem Interneta ili pristup lokalnom proxyju, a svi znamo kako su te stvari općenito nepouzdane.

Srećom, postoje različiti načini raspoređivanja ovisnosti zajedno s aplikacijom (aplikacijama), na primjer u pretpakiranom spremniku za implementaciju u oblaku.

5.1. Pokretanje aplikacije za zagrijavanje

Najjednostavniji način predmemoriranja ovisnosti je izvršavanje zagrijavanja aplikacije u ciljnom okruženju. Kao što smo vidjeli ranije, to će uzrokovati preuzimanje i spremanje ovisnosti u lokalno spremište Maven. Ako pokrenemo više aplikacija, spremište će na kraju sadržavati sve ovisnosti bez duplikata.

Budući da pokretanje aplikacije može imati neželjene nuspojave, možemo izvršiti i "suho pokretanje" koje samo rješava i preuzima ovisnosti bez pokretanja bilo kojeg korisničkog koda:

$ java -Dthin.dryrun = true -jar moja-aplikacija-1.0.jar

Imajte na umu da, prema konvencijama Spring Boot-a, možemo postaviti -Tanja.suha svojstvo također s a –Tanak.dryrun argument naredbenog retka za aplikaciju ili s THIN_DRYRUN svojstvo sustava. Bilo koja vrijednost osim lažno uputit će Thin Launcher za izvođenje na suho.

5.2. Pakiranje ovisnosti tijekom gradnje

Druga mogućnost je prikupljanje ovisnosti tijekom gradnje, bez spajanja u JAR. Zatim ih možemo kopirati u ciljno okruženje kao dio postupka implementacije.

To je općenito jednostavnije jer nije potrebno pokretati aplikaciju u ciljanom okruženju. Međutim, ako implementiramo više aplikacija, morat ćemo spojiti njihove ovisnosti, bilo ručno ili skriptom.

Format u kojem Tanki dodatak za Maven i Gradle pakira ovisnosti tijekom gradnje jednak je Mavenovom lokalnom spremištu:

root / spremište / com / net / org / ...

U stvari, možemo pomoću aplikacije Thin Launcher uputiti bilo koji takav direktorij (uključujući lokalno spremište Maven) tijekom izvođenja s tanak.korijen svojstvo:

$ java -jar my-app-1.0.jar --thin.root = moja-aplikacija / deps

Također možemo sigurno spojiti više takvih direktorija kopiranjem jednog preko drugog, čime dobivamo Mavenovo spremište sa svim potrebnim ovisnostima.

5.3. Pakiranje ovisnosti s Mavenom

Da bi Maven spakirao ovisnosti umjesto nas, koristimo odlučnost cilj dodatak spring-boot-thin-maven-plugin. Možemo ga pozvati ručno ili automatski u našem pom.xml:

 org.springframework.boot.experimental spring-boot-thin-maven-plugin $ {thin.version} rješavanje rješavanje false 

Nakon izgradnje projekta, pronaći ćemo direktorij cilj / tanak / korijen / sa strukturom o kojoj smo govorili u prethodnom odjeljku.

5.4. Pakiranje ovisnosti s Gradleom

Ako koristimo Gradle s tanko-bacač dodatak, umjesto toga, imamo tankoRješiti zadatak dostupan. Zadatak će spremiti program i njegove ovisnosti u graditi / tanko / korijen / direktorij, slično kao dodatak Maven iz prethodnog odjeljka:

$ gradlew thinResolve

Imajte na umu da je u vrijeme pisanja članka tanko-bacač dodatak ima bug koji sprečava spremanje ovisnosti ako tanka.svojstva koristi se: //github.com/dsyer/spring-boot-thin-launcher/issues/53.

6. Zaključci i daljnje čitanje

U ovom smo članku pogledali kako napraviti tanku teglu. Također smo vidjeli kako koristiti Maven infrastrukturu za preuzimanje i pohranu njihovih ovisnosti.

Početna stranica tankog pokretača sadrži još nekoliko vodiča HOW-TO za scenarije poput postavljanja oblaka na Heroku, kao i cjelovit popis podržanih argumenata naredbenog retka.

Implementacija svih primjera Mavena i isječaka koda može se naći u projektu GitHub - kao Maven projekt, tako da bi ga trebalo biti lako uvesti i pokrenuti takav kakav jest.

Slično tome, svi primjeri Gradlea odnose se na ovaj GitHub projekt.