Ultima modificare: 7 aprilie 2020

spring

Tocmai am anunțat noul curs Learn Spring, axat pe fundamentele Spring 5 și Spring Boot 2:

1. Introducere

În acest tutorial, ne vom uita la cum să construiți un proiect Spring Boot într-un fișier JAR subțire, utilizând proiectul spring-boot-thin-launcher.

Spring Boot este cunoscut pentru implementările sale JAR „grase”, unde un singur artefact executabil conține atât codul aplicației, cât și toate dependențele sale.

Boot-ul este, de asemenea, utilizat pe scară largă pentru a dezvolta microservicii. Uneori, acest lucru poate fi în contradicție cu abordarea „JAR grăsime”, deoarece includerea acelorași dependențe în multe artefacte poate deveni o risipă importantă de resurse.

2. Condiții prealabile

În primul rând, avem nevoie de un proiect Spring Boot, desigur. În acest articol, vom analiza versiunile Maven și versiunile Gradle în configurațiile lor cele mai comune.

Este imposibil să acoperiți toate sistemele de construcție și configurațiile de construcție, dar, sperăm, vom vedea suficient de multe principii generale pe care ar trebui să le puteți aplica la configurarea dvs. specifică.

2.1. Proiecte Maven

Într-un proiect Boot construit cu Maven, ar trebui să avem pluginul Spring Boot Maven configurat în fișierul pom.xml al proiectului nostru, părintele sau unul dintre strămoșii săi:

Versiunea dependențelor Spring Boot este de obicei decisă folosind un BOM sau moștenind de la un POM părinte ca în proiectul nostru de referință:

2.2. Proiecte Gradle

Într-un proiect Boot construit cu Gradle, vom avea pluginul Boot Gradle:

Rețineți că, în acest articol, vom lua în considerare doar Boot 2.x și proiecte ulterioare. Thin Launcher acceptă și versiunile anterioare, dar necesită o configurație Gradle ușor diferită pe care o omitem pentru simplitate. Vă rugăm să consultați pagina principală a proiectului pentru mai multe detalii.

3. Cum se creează un JAR subțire?

Spring Boot Thin Launcher este o mică bibliotecă care citește dependențele unui artefact dintr-un fișier inclus în arhivă, le descarcă dintr-un depozit Maven și lansează în cele din urmă clasa principală a aplicației.

Asa de, când construim un proiect cu biblioteca, obținem un fișier JAR cu codul nostru, un fișier care enumeră dependențele sale și clasa principală din bibliotecă care efectuează sarcinile de mai sus.

Desigur, lucrurile sunt puțin mai nuanțate decât explicația noastră simplificată; vom discuta în detaliu câteva subiecte mai târziu în articol.

4. Utilizare de bază

Să vedem acum cum să construim un JAR „subțire” din aplicația noastră obișnuită Spring Boot.

Vom lansa aplicația cu java -jar obișnuit, cu argumente suplimentare opționale pe linia de comandă care controlează Thin Launcher. Vom vedea câteva dintre ele în secțiunile următoare; pagina de pornire a proiectului conține lista completă.

4.1. Proiecte Maven

Într-un proiect Maven, trebuie să modificăm declarația pluginului Boot (vezi secțiunea 2.1) pentru a include o dependență de aspectul personalizat „subțire”:

Lansatorul va citi dependențele din fișierul pom.xml stocat de Maven în JAR-ul generat în directorul META-INF/maven.

Vom efectua construcția ca de obicei, de exemplu, cu mvn install.

Dacă dorim să putem produce atât subțiri cât și subțiri (de exemplu într-un proiect cu module multiple) putem declara aspectul personalizat într-un profil dedicat Maven.

4.2. Maven și dependențe: thin.properties

De asemenea, putem cere ca Maven să genereze un fișier thin.properties în plus față de pom.xml. În acest caz, fișierul va conține lista completă a dependențelor, inclusiv cele tranzitive, iar lansatorul o va prefera peste pom.xml.

Mojo (plugin) pentru a face acest lucru este spring-boot-thin-maven-plugin: properties și, în mod implicit, scoate fișierul thin.properties în src/main/resources/META-INF, dar putem specifica locația acestuia cu proprietatea thin.output:

Rețineți că directorul de ieșire trebuie să existe pentru ca obiectivul să aibă succes, chiar dacă l-am păstrat pe cel implicit.

4.3. Proiecte Gradle

În schimb, într-un proiect Gradle, adăugăm un plugin dedicat:

Pentru a obține o construcție subțire, îi vom spune lui Gradle să execute sarcina thinJar:

4.4. Gradle și dependențe: pom.xml

În exemplul de cod din secțiunea anterioară, am declarat pluginul Maven în plus față de Thin Launcher (precum și pluginurile Boot și Dependency Management pe care le-am văzut deja în secțiunea Prerequisites).

Asta pentru că, la fel ca în cazul Maven pe care l-am văzut mai devreme, artefactul va conține și va folosi un fișier pom.xml care enumeră dependențele aplicației. Fișierul pom.xml este generat de o sarcină numită thinPom, care este o dependență implicită a oricărei sarcini jar.

Putem personaliza fișierul pom.xml generat cu o sarcină dedicată. Aici, vom replica doar ceea ce face deja pluginul subțire automat:

Pentru a utiliza fișierul nostru personalizat pom.xml, adăugăm sarcina de mai sus la dependențele sarcinii jar:

4.5. Gradle și dependențe: thin.properties

Putem, de asemenea, Gradle să genereze un fișier thin.properties mai degrabă decât pom.xml, așa cum am făcut mai devreme cu Maven.

Sarcina care generează fișierul thin.properties se numește thinProperties și nu este utilizată în mod implicit. Îl putem adăuga ca dependență a sarcinii jar:

5. Stocarea dependențelor

Întregul punct al borcanelor subțiri este de a evita gruparea dependențelor cu aplicația. Cu toate acestea, dependențele nu dispar magic, sunt pur și simplu stocate în altă parte.

În special, Thin Launcher folosește infrastructura Maven pentru a rezolva dependențele, deci:

    verifică depozitul local Maven, care implicit se află

/.m2/repository dar poate fi mutat în altă parte;

  • apoi, descarcă dependențele lipsă din Maven Central (sau orice alt depozit configurat);
  • în cele din urmă, le cache în depozitul local, astfel încât nu va trebui să le descarce din nou data viitoare când vom rula aplicația.
  • Desigur, faza de descărcare este partea lentă și predispusă la erori a procesului, deoarece necesită acces la Maven Central prin Internet sau acces la un proxy local și știm cu toții cum acele lucruri nu sunt de încredere.

    Din fericire, există diferite modalități de implementare a dependențelor împreună cu aplicația (aplicațiile), de exemplu într-un container preambalat pentru implementare în cloud.

    5.1. Rularea aplicației pentru încălzire

    Cel mai simplu mod de a memora în cache dependențele este de a efectua o rundă de încălzire a aplicației în mediul țintă. După cum am văzut mai devreme, acest lucru va face ca dependențele să fie descărcate și memorate în cache în depozitul local Maven. Dacă rulăm mai multe aplicații, depozitul va ajunge să conțină toate dependențele fără duplicate.

    Deoarece rularea unei aplicații poate avea efecte secundare nedorite, putem, de asemenea, efectua o „alergare uscată” care rezolvă și descarcă dependențele numai fără a rula niciun cod de utilizator:

    Rețineți că, conform convențiilor Spring Boot, putem seta proprietatea -Dthin.dryrun și cu un argument de linie de comandă –thin.dryrun la aplicație sau cu o proprietate de sistem THIN_DRYRUN. Orice valoare, cu excepția falsului, va instrui Thin Launcher să efectueze o rulare uscată.

    5.2. Ambalarea dependențelor în timpul construcției

    O altă opțiune este de a colecta dependențele în timpul construcției, fără a le grupa în JAR. Apoi, le putem copia în mediul țintă ca parte a procedurii de implementare.

    Acest lucru este, în general, mai simplu, deoarece nu este necesar să rulați aplicația în mediul țintă. Cu toate acestea, dacă implementăm mai multe aplicații, va trebui să le combinăm dependențele, fie manual, fie cu un script.

    Formatul în care Thin Plugin pentru Maven și Gradle împachetează dependențele în timpul unei compilări este același cu un depozit local Maven:

    De fapt, putem direcționa o aplicație utilizând Thin Launcher către orice astfel de director (inclusiv un depozit local Maven) în timp de execuție cu proprietatea thin.root:

    De asemenea, putem îmbina în siguranță mai multe astfel de directoare copiindu-le unul peste altul, obținând astfel un depozit Maven cu toate dependențele necesare.

    5.3. Împachetarea dependențelor cu Maven

    Pentru ca Maven să împacheteze dependențele pentru noi, folosim obiectivul de rezolvare al pluginului spring-boot-thin-maven. Îl putem invoca manual sau automat în pom.xml:

    După construirea proiectului, vom găsi un director target/thin/root/cu structura pe care am discutat-o ​​în secțiunea anterioară.

    5.4. Ambalarea dependențelor cu Gradle

    Dacă folosim Gradle cu pluginul de lansare subțire, avem în schimb o sarcină thinResolve disponibilă. Sarcina va salva aplicația și dependențele sale în directorul build/thin/root /, similar cu pluginul Maven din secțiunea anterioară:

    Vă rugăm să rețineți că, în momentul scrierii, pluginul de lansare subțire are o eroare care împiedică salvarea dependențelor dacă este utilizat thin.properties: https://github.com/dsyer/spring-boot-thin-launcher/ numere/53.

    6. Concluzii și lecturi suplimentare

    În acest articol, ne-am uitat la modul de realizare a borcanului nostru subțire. De asemenea, am văzut cum să folosim infrastructura Maven pentru a descărca și stoca dependențele acestora.

    Pagina de pornire a lansatorului subțire mai are câteva ghiduri CUM-TO pentru scenarii, cum ar fi implementările în cloud către Heroku, precum și lista completă a argumentelor de linie de comandă acceptate.

    Implementarea tuturor exemplelor Maven și a fragmentelor de cod poate fi găsită în proiectul GitHub - ca proiect Maven, deci ar trebui să fie ușor de importat și rulat așa cum este.

    În mod similar, toate exemplele Gradle se referă la acest proiect GitHub.