Cum sa creezi o adnotare in Java – Decoratori pentru campuri

Adnotarile sunt o modalitate prin care putem scapa de mult cod boilerplate si prin care putem prelua controlul unor Clase, Metode si Campuri inainte de a fi folosite in contextul aplicatiei noastre.

Ele intra in categoria decoratorilor care adauga metadate peste aceste elemente si ne permit, prin minunatul java reflection, sa le manipulam dupa voia noastra, fara a fi nevoie de un pas suplimentar de discriminare.

De asemenea, toate facilitatile Java Reflection sunt indreptate spre scopul de a ne oferi un control ierarhic cat mai high-level asupra claselor pe care le manipulam.

Cum construim o adnotare

Pentru a incepe sa ne adaugam adnotarile, ar trebui sa intelegem urmatoarele proprietati ale acestora. Exemplul cu care vom lucra:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Tutorial {

}

Asadar, observam doua adnotari ce semnifica proprietatile adnotarii noastre Tutorial:

  • @Retention – reprezinta durata de viata a adnotarii noastre. Valorile posibile sunt:
    • RetentionPolicy.SOURCE – adnotarea noastra va disparea la compilare. Folositi aceasta adnotare in cazul in care vreti sa adaugati informatii despre codul vostru sursa si sa le interpretati intr-un tool extern.
    • RetentionPolicy.CLASS – adnotarea va ajunge in clasa compilata, insa nu este obligatoriu ca ea sa fie interpretata de JVM. Folositi aceasta politica de retentie daca urmariti sa va construiti propriul classloader care va avea acces la decoratorii vostri.
    • RetentionPolicy.RUNTIME – adnotarea va ajunge in clasa compilata si va fi obligatoriu vizibila in interiorul JVM-ului. Aceasta este alegerea pentru acest tutorial.
  • @Target – Reprezinta constrangerea utilizarii adnotarilor, practic, pe ce se poate aplica aceast nou decorator. Valorile posibile sunt:
    • ElementType.ANNOTATION_TYPE – adnotarea se poate aplica pe alte adnotari (Inception much).
    • ElementType.CONSTRUCTOR – adnotarea se poate aplica pe constructorii claselor voastre.
    • ElementType.FIELD – adnotarea se poate aplica pe campurile unei clase.
    • ElementType.LOCAL_VARIABLE – adnotarea se poate aplica pe campurile locale ale clasei.
    • ElementType.METHOD – adnotarea se poate aplica pe o metoda.
    • ElementType.MODULE – adnotarea se poate aplica pe un modul Java (Java 9+).
    • ElementType.PACKAGE – adnotarea se poate aplica pe un pachet Java.
    • ElementType.PARAMETER – adnotarea se poate aplica pe un parametru dintr-un constructor sau metoda.
    • ElementType.TYPE – adnotarea se poate aplica pe un Java Type precum clase, interfete, enum sau alte adnotari.
    • ElementType.TYPE_PARAMETER – adnotarea se poate aplica pe variabilele generice de tip.
    • ElementType.TYPE_USE – adnotarea se poate aplica pe folosirea unui Java Type, precum instantierea, castarea sau implementarea unei interfete.

Pentru a continua explicatiile de mai sus, trebuie folosim cuvantul cheie @interface pentru a preciza explicit ca ceea ce vom defini in interiorul acestei interfete, si anume: o adnotare.

Pssst…: Daca vrei sa inveti Java de la 0, sau vrei sa iti aprofundezi cunostintele, am cursul perfect pentru tine – vezi aici

Cum adaugam parametri in adnotarea noastra

Utilitatea unei adnotari este formata din doua parti:

  • Faptul ca putem discrimina o clasa / metoda / un camp si putem sa ne folosim de aceasta informatie atunci cand il/o folosim.
  • Faptul ca putem parametriza acest discriminator prin valorile parametrilor sai.

Un exemplu de astfel de use-case este adnotarea @Table parte din JPA care ne permite sa specificam numele tabelului SQL pe care vrem sa il creeze Hibernate pentru entitatea noastra (@Table(„studenti”)).

Pentru a adauga parametri adnotarii noastre, putem folosi urmatoarea structura:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Tutorial {
	 public String value() default "";
}

Dupa cum poti vedea, parametri se adauga precum metodele in interefete, fara implementare si cu o valoare default. Pentru a trimite acest parametru intr-un camp adnotat cu @Tutorial putem scrie:

public class AnnotatedClass {
	
	@Tutorial("parametru")
	private int age;
}

Si asignam valoarea campului value din adnotarea @Tutorial valorea parametru. Aceasta metoda este utilizabila doar in cazul in care avem un singur parametru in adnotare, altfel, va trebui o notatie de forma:

public class AnnotatedClass {
	
	@Tutorial(value = "parametru", param1 = 1, param2 = "parametru")
	private int age;
}

In cazul in care nu specificam o valoare a unui parametru, acesta va lua automat valoarea default din definitia adnotarii.

Cum adaugam parametri in adnotarea noastra

Folosind Java.Lang.Reflect vom citi campurile din clasa noastra, il vom cauta pe cel adnotat cu @Tutorial si ii vom afisa valoarea parametrului value astfel:

public class SpringtestApplication {

	public static void main(String[] args) {
		Class<AnnotatedClass> ourClass = AnnotatedClass.class;
		for (Field field : ourClass.getDeclaredFields()) {
			if (field.isAnnotationPresent(Tutorial.class)) {
				Annotation ourAnnotation = field.getAnnotation(Tutorial.class);
				Tutorial tutorialAnnotation = (Tutorial) ourAnnotation;
				
				System.out.println("Am gasit adnotarea @Tutorial");
				System.out.println(tutorialAnnotation.value());

			}
		}
	}
}

Traducerea liniilor de cod de mai sus este urmatoarea:

Pentru fiecare camp din clasa AnnotatedClass sub instanta sa, ourClass, cautam adnotarea Tutorial prin apelul isAnnotationPresent(adnotareCautata). Cand o gasim, castam adnotarea gasita in Tutorial.class si ii citim parametri.

Putem face acest lucru atat la nivel de metoda, cat si la nivel de Observer daca dorim sa reactionam la prezenta uneia sau mai multor adnotari sau valori.

Concluzie

Adnotarile Java ne permit sa extindem functionalitatile pe care ni le dorim in limbajul Core, adaugand decoratori peste clase, metode si campuri. Odata ce procesul descris mai sus este aplicat de 5-6 ori, iti va fi foarte usor sa il aplici in cazurile din viata reala, unde consideri ca ar fi util.

Nu te arunca la decorarea excesiva – deoarece ea prezinta doua riscuri:

  • Codul devine mai greu de inteles pentru colegii tai.
  • Testarea unitara a adnotarilor este dificila – direct proportionala cu numarul de parametri pe care ii vei declara in interior.

Sper sa iti fie de ajutor, spor la joaca!

Lombok – Cum sa fii lenes si elegant

Project Lombok a fost construit cu un singur scop: sa scape de partea verbose din codul Java. Cunosc multi programatori care nu-si pot inchipui viata fara Lombok – il adauga in lista de dependinte core pe care o folosesc la pornirea oricarui proiect nou. Echipe intregi au petrecut luni de zile refactorizand cod legacy, avand ca prioritate introducerea acestui modul.

Nivel Dificultate: Mediu

Daca este intr-adevar atat de util – tu decizi! Sa vedem ce ofera acest proiect.

Project Lombok – Maven

Pentru a incepe sa folosesti adnotarile Lombok, primul pas este acela de a-l adauga ca dependinta in fisierul pom:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
    <scope>provided</scope>
</dependency>

Un maven clean install iti va aduce cele necesare pentru a incepe.

Project Lombok – Eleganta entitatilor

Daca ai lucrat pana acum la un proiect Java Enterprise, sunt convins ca urmatorul exemplu de clasa iti este familiar:

@Entity
@Table(name = "notifications")
public class Notification {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long userId;
    private String message;
    private String title;
    private boolean seen;
    private Timestamp time;
    
    public Notification(){}

    public Notification(Long userId, String message, String title){
       this.userId = userId;
       this.message = message;
       this.title = title;
    }


    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean isSeen() {
        return seen;
    }

    public void setSeen(boolean seen) {
        this.seen = seen;
    }

    public Timestamp getTime() {
        return time;
    }

    public void setTime(Timestamp time) {
        this.time = time;
    }
}

Aceasta este o clasa care reprezinta o notificare in cadrul unui proiect web. Aceasta este adnotata cu @Entity pentru a fi interpretata de JPA, de unde tragem concluzia ca nu vom avea logica de business – este un model standard de entitate care urmeaza a fi plimbata din baza de date catre backend de cateva mii de ori pe ora.

Pssst…: Daca vrei sa inveti Java de la 0, sau vrei sa iti aprofundezi cunostintele, am cursul perfect pentru tine – vezi aici

Observam ca o mare parte din aceasta clasa este ocupata de getteri, setteri si constructor. Pentru o persoana de business (cum le place lor sa te intituleze), codul de mai sus se poate rezuma in „O notificare are un titlu, un mesaj, un id de utilizator si o data la care a fost generata” – tot ce este pe langa aceste informatii este considerat boilerplate code si sare din ecuatie daca folosim Lombok.

Asa ar arata versiunea refactorizata a acestei clase, folosindu-ne de adnotarile noi:

@Entity
@Table(name = "notifications")
@Getter @Setter @NoArgsConstructor
public class Notification {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long userId;
    private String message;
    private String title;
    private boolean seen;
    private Timestamp time;

    public Notification(){}
    
    public Notification(Long userId, String message, String title){
       this.userId = userId;
       this.message = message;
       this.title = title;
    }
}

Dupa cum vezi, am scurtat codul cu 48 de linii, folosind cele 3 noi adnotari:

  • @Getter – care va genera automat cate o metoda de tip getter pentru fiecare camp introdus.
  • @Setter – care va genera automat cate o metoda de tip setter pentru fiecare camp introdus.
  • @NoArgsConstructor – care va genera un constructor fara parametrii, pentru a nu-l pierde atunci cand il facem pe cel cu parametri din exemplu de mai sus.

Lombok face aceste adaugiri in momentul build-ului, injectand cod nou Java in ByteCode-ul proiectului tau, ajungand in fisierele .class acelasi cod pentru ambele exemple prezentate.

Ce facem in cazul in care vrem sa schimba modificatorul de acces pentru un anumit camp? Simplu:

private @Getter(AccessLevel.PRIVATE) double ratingScore;

Aceasta proprietate se poate adauga si la adnotarea @Setter.

Ce facem daca vrem sa eliminam doar un subset de campuri dintr-o entitate pentru care vrem ca Lombok sa ne genereze getteri si setteri? Simplu:

private @Getter(AccessLevel.NONE) int age;

Aceasta proprietate se poate adauga si la adnotarea @Setter.

Vrei sa adaugi constrangeri de null campurilor tale? Poti folosi adnotarea @NonNull pe care o poti folosi atat la definirea variabilelor:

private final @NonNull String name;

… care va adauga verificari de nulitate peste acest camp atunci cand va fi accesat, sau in lista de parametri ai unei metode:

public void computeSum(@NonNull Number firstNumber, @NonNull Number secondNumber)

… caz in care Lombok va adauga o verificare de nulitate care va arunca un NullPointerException in cazul in care il vei trimite null.

Putem uita si de autogenerarea metodelor toString() si equals() / hashCode() folosind adnotarile corespunzatoare:

  • @ToString – care va oferi implementarea default a metodei toString() care include toate campurile clasei.
  • @EqualsAndHashCode – care ofera o implementare desteapta a metodelor equals() si hashCode() ce tine cont de campurile pe care el le considera potrivita.

In cazul in care dorim generarea setterilor fluenti, adica sa activam constructii fluente ale instantierii claselor, avem doua optiuni:

Putem folosi adnotarea @Accessors cu atributul fluent=true care va genera setteri fluenti (in loc de setAge(), va genera age()):

@Accessors(fluent = true) @Getter @Setter
public class Record {
   private int value;
   private String name;
}

… care ne va permite sa construim obiectul astfel:

Record record = new Record()
      .value(100)
      .name("Example Record");

Sau putem folosi adnotarea @Builder ce ne permite sa construim un Builder mult mai usor:

@Builder
public class Record {
   private int value;
   private String name;
}

… si ne permite sa folosim:

Record record = Record.builder()
   .value(100)
   .name("Example Record")
   .build();

Un alt capitol la care ne ajuta Lombok sa scapam de linii de cod inutile (si aici sunt 100% de acord) este logging-ul. Decat sa tot initializam loggerul in fiecare clasa unde avem nevoie de el, putem folosi implementarea Slf4j disponibila in Lombok astfel:

@Slf4j
private class RecordService{
   public void testLogging(){
      log.debug("Logging works!");
}}

Sau, in cazul in care nu vrei sa folosesti Slf4j, Lombok ofera suport si adnotarilor: @Log, @Log4j, @XSlf4j.

Daca vrei sa iti creezi clase imutabile, poti folosi adnotarea @Value care va autogenera codul din clasa respectiva pentru a se asigura ca, intr-adevar, este imutabila. Ai grija cum o folosesti – prea multe clase imutabile, intr-un proiect enterprise, pot fi o sursa de risc in domeniul performantei acesteia.

Project Lombok – Concluzie

Pentru cei dintre voi care credeti ca sunteti mai productivi daca nu scrieti atat cod, aceasta librarie este ideala. Aveti insa grija la problemele de performanta si securitate pe care le introduce folosirea adnotarilor Lombok – ele pot fi ascunse in clase foarte mici si greu sesizabile datorita lipsei de verbose in clasele noastre. Un exemplu concret ar fi folosirea @Value atunci cand nu este cazul.

Eu nu folosesc si nici nu sunt mare fan – vorbeste omul care adauga inclusiv atributele cu valori default din cadrul Spring pentru a ma asigura ca, in viitor, cand se va face un version bump la vreo librarie pe care o folosesc, sa nu ma trezesc cu acele valori default schimbate si cu cod care sa nu mai functioneze complete.

Nu am acoperit toate adnotarile si metodele oferite de Lombok, insa, pentru a le citi in intregime, poti intra aici.

In rest, spor la joaca!

JDK 13 – Tot ce trebuie sa stii despre Text Block si noile Switch-uri

De cand Oracle a schimbat politica de incrementare a versiunilor (decizie intampinata cu multa dezamagire de mai multi experti din domeniu) – update-urile au inceput sa se contureze, tinzand catre modelul altor tehnologii aflate pe piata in momentul de fata. Odata cu JDK 13, s-au introdus cateva schimbari ale API-ului ce sta la baza Java, cat si unele elemente aditionale care sa usureze lucrul cu cele mai populare structuri de date in aplicatiile enterprise.

            In acest articol iti voi expune modificarile introduse in aceasta versiune, alaturi de cateva bucati de cod care sa te ajute sa intelegi ce se va schimba in viata ta de programator daca alegi sa iti actualizezi proiectele existente.

JEP355 – Text Blocks (blocuri complexe de text)

Acest feature se afla inca in stadiul de Preview – adica folosirea lui poate cauza probleme in aplicatii complexe si nu este recomandat pentru proiectele aflate deja in productie.

            Motivatia care a stat la baza introducerii acestei noi reprezentari ale String-ului este nevoia programatorilor de a manipula structuri de date precum JSON sau XML in cadrul metodelor lor, fara a fi nevoie de artificii de afisare precum apendarea unui line-break ( ‘\n’ ). Asadar, daca dorim sa reprezentam un obiect de tip String pe mai multe linii, vom putea folosi o suita de 3 ghilimele, in loc de una, care era standardul pana acum. Declararea obiectului si numele sau raman aceleasi:

Exemplu String de o singura linie:

String jdkVersionName = “JDK 13”;

Exemplu String multi-line:

String myJson = “”” 
		{
                    “name” : “Java Development Kit”,
                    “version”: 13
		}
		“””;

            Tine cont de urmatoarele reguli:

  1. Nu poti initializa valoarea unui obiect de tip String de o singura linie folosind cele 3 ghilimele (“””) – facand acest lucru te vei trezi cu o eroare de forma “illegal text block open delimiter sequence, missing line terminator”.
  2. Escaparea ghilimelelor (“) in acest caz va trebui facuta doar in cazul in care se regasesc 3 ghilimele in serie, una dupa alta – deci poti reprezenta blocuri JSON, HTML si XML fara a-ti face probleme de escapare a ghilimelelor din acestea.
  3. Indentarea finala a blocului de text este dependenta de locatia celor 3 ghilimele care-l inconjoara – in exemplul de mai sus, indentarea va porni de la nivelul primului set de ghilimele, deci prima acolada din JSON va fi la nivelul 0, apoi fiecare element-copil va avea indentarea relativa la acest nivel (i.e: elementul “name” va fi la nivelul 1, etc).
  4. In exemplul de mai sus, in cazul afisarii variabilei “myJson” se va observa un rand aditional gol aflat dupa ultima acolada din reprezentarea JSON – pentru a-l elimina, poti muta cele 3 ghilimele de incheiere pe acelasi rand cu aceasta acolada.

Cum precizam mai sus, acest feature este inca in stadiul Preview – asadar, pentru a avea acces la el trebuie sa activezi tot pachetul de astfel de feature-uri prin execturea comenzii:

java --enable-preview 

Odata cu acest nou sistem de reprezentare a stringurilor multi-line, obtinem si 3 noi metode parte din clasa String:

  1. formatted() – aceasta metoda foloseste chiar valoarea stringului din care este apelat drept formatter.
  2. stripIndent() – metoda care va elimina spatiile in plus fata de indentarea standard si va lasa structura finala curata cu indentare standard.
  3. translateEscapes() – metoda care va inlocui caracterele de escapare (precum \r) cu valoarea lor Unicode.

Poti citi mai multe despre TextBlock aici si aici.

JEP354 – Expresii switch noi

            In minunatul univers al structurilor decizionale ale limbajului Java, cel mai refactorizat bloc este switch-ul. Dupa update-ul “major” care ne-a permis sa facem switch peste String-uri, baietii s-au gandit putin la scenariile de utilizare a acestei structuri, rezultand un artificiu interesant si folositor in peste 70% din cazurile din lumea reala.

            Eu unul evit switch-urile cat mai mult deoarece nu consider ca sunt usor de inteles pentru orice alta persoana care interactioneaza cu codul meu si, poate cel mai important, este foarte complicat de refactorizat sau actualizat. De multe ori am vazut cum oamenii folosesc switch-ul ca o portita spre spaghetti code si am citit astfel de blocuri de zeci de linii aflate fara noima intr-un switch ce a inceput de la 8 linii.

Pssst…: Daca vrei sa inveti Java de la 0, sau vrei sa iti aprofundezi cunostintele, am cursul perfect pentru tine – vezi aici

            Hai sa vedem ce ne permite noul switch, aflat tot in stadiul Preview:

int numberRating =  switch (starRating) {
		case ONESTAR:
		case TWOSTAR:
			yield 5;
		case THREESTAR:
			yield 7;
		case FOURSTAR:
			yield 9;
		case FIVESTAR:
			yield 10;
		default:
			throw new IllegalStateException(“Star not identified: “ + starRating);
		}

Asadar, daca vrem sa schimbam valoarea unei variabile in functie de branch-ul de switch in care intra conditia noastra, vom putea folosi yield + valoare in loc de asignarea valorii + break; cum eram obisnuiti pana acum – eu stiu sigur ca voi putea inlocui multe if/else si switch-uri vechi cu aceasta noua structura.

            Ai grija la tratarea cazului default, pentru ca poti ajunge in situatia in care nu poti trata logic exceptia aruncata. In cazul in care vrei o valoare default a variabilei schimbate, asigura-te ca se potriveste cu logica de business unde o folosesti. Riscurile acestui nou switch sunt asemanatoare cu cele ale transformarilor lambda ale structurilor din Java 5 / 6 / 7, nu te grabi in a decide avantajele folosirii unei structuri decizionale sau a alteia, ci incearca pe cat posibil sa gasesti cea mai sustenabila metoda de a-ti scrie codul.

Concluzie

Nu uita ca stadiul Preview aduce cu sine posibile buguri sau lipsuri in implementarea noilor functionalitati si ca te poti trezi cu metodele marcate drept deprecated de la o versiune la alta. De altfel vei observa ca metodele noi din String sunt deja marcate astfel in ideea in care, in functie de feedback-ul developerilor, ele pot suferi modificari sau pot fi chiar eliminate si te vei trezi cu erori de compilare greu de digerat.

            Daca iti place sa experimentezi sau vrei sa fii cu un pas in fata ciclului de update-uri JDK, incearca sa alegi 2-3 clase dintr-un proiect in care se preteaza una din cele doua noi concepete si treci la refactorizat – nu uita sa creezi un branch nou in care sa remodelezi codul si, in cazul in care ele vor iesi din preview neafectate, vei un avantaj maricel in ceea ce priveste nivelul tehnologic la care se va afla aplicatia ta.

Schelet proiect Spring Boot (incepatori)

Incepem in forta! Astazi va voi arata cum sa porniti un proiect Java folosind framework-ul Spring.

Nivel Dificultate: Incepatori

Spring este unul dintre cele mai populare framework-uri folosite impreuna cu Java. De ce?

  • Este suportat de majoritatea providerilor de sisteme Cloud.
  • Ai un proiect functional in mai putin de 10 minute.
  • Este compatibil cu majoritatea librariilor third-party folosite in majoritatea proiectelor (i.e nu intra in conflict cu alte librarii).
  • Ofera suport gratuit si foarte bine structurat.
  • Este integrat in cele doua principale IDE-uri de pe piata pentru programarea Java (IntelliJ si Eclipse / STS).
  • Iti va fi foarte usor sa configurezi modulul de persistenta (Hibernate) prin fisierul de configurare implicit (application.properties).
  • Nu ai nevoie de un server (container) pentru a rula aplicatia local (prin Spring Boot)
  • Daca nu te-am convins inca, citeste mai multe aici.

Asadar am decis ca ne place Spring-ul, super! Sa trecem la treaba.

Sunt doua modalitati de a include Spring-ul ca framework in aplicatiile noastre.

  1. Construim un proiect nou Java -> adaugam suport pentru Maven -> adaugam dependintele specifice Spring-ului manual.
  2. Folosim acest tool online pentru a ne genera o structura de baza si scapam de munca manuala.

Pentru ca nu are absolut niciun sens sa abordam prima varianta acum (pentru ca are sanse mai mari de esec, avand in vedere ca acest articol este indreptat catre incepatori), o vom alege pe cea din urma.

1. Detalii de baza

In prima faza, Spring Initializr ne va intreba ce buildtool si ce limbaj de programare folosim in proiectul nostru. In cazul de fata voi alege Maven si Java.

Apoi ne intreaba ce versiune de Spring Boot vrem sa folosim in structura noastra. Sugestia mea este sa va feriti de versiunile care au cuvantul SNAPSHOT in nume, deoarece acestea pot contine buguri si functionalitati care nu au fost 100% testate.

Mai departe trecem la datele de baza ale proiectului nostru. Observam ca ni se cere o structura specifica:

  • Group – reprezinta un nume unic care sa identifice proiectul (de regula, acest camp este completat cu domeniul detinut de tine, scris invers – i.e: ro.vladbutnaru sau org.apache)
  • Artifact – reprezinta numele modului din proiect pe care il construiesti folosind aceasta structura (i.e: test).

2. Dependinte

Urmatorul pas este cel al adaugarii dependintelor pe care le vei folosi in proiect. Nu-ti bate capul prea mult cu gasirea acestora deoarece acest pas il poti continua adaugand manual in fisierul de proprietati Maven sau Gradle mai tarziu.

Pentru scheletul nostru vom folosi cateva librarii de baza care sa ne permita expunerea unui serviciu web REST si conectarea la o baza de date MySQL. Asadar, vom cauta si alege din lista urmatoarele:

  • Spring Web
  • Spring Data JPA
  • MySQL Driver

In cele din urma vom finaliza acest formular prin butonul verde Generate si vom descarca arhiva zip care contine proiectul nostru.

Screenshot – Campuri completate Spring Initializr

3. Urmatorii pasi

Arhiva descarcata va contine un proiect Maven sau Gradle pe care il putem importa in IDE-ul nostru preferat (IntelliJ sau Eclipse/STS) si sa continuam sa dezvoltam modulul dorit.

Pssst…: Daca vrei sa inveti Java de la 0, sau vrei sa iti aprofundezi cunostintele, am cursul perfect pentru tine – vezi aici

Pentru a putea rula acest proiect folosindu-ne de Spring Boot Starter, va trebui sa adaugam o configurare de executie astfel:

  • Eclipse
    • Click dreapta pe proiectul importat
    • Selecteaza Run As
    • Selecteaza Maven build…
    • In noua fereastra, in campul Goals scrie „spring-boot:run”.
    • Selecteaza Apply & Run
  • IntelliJ
    • Selecteaza Run Configurations
    • Selecteaza Add new
    • Selecteaza din lista Maven
    • Apasa pe butonul cu simbol de „+” verde Add
    • In campul Goals scrie „spring-boot:run”
    • Selecteaza Apply & Run

Concluzie

Dupa cum ai observat, am construit un schelet de proiect Java, folosind Spring Initializr pe care l-am si executat in doar 10 minute. Iti recomand sa creezi 2-3 proiecte pentru a consolida pasii pe care i-ai citit aici, pe blog, si pentru a te obisnui cu acest workflow. Desi nu te vei lovi extraordinar de des de procesul inceperii unui proiect de la 0, iti va fi util sa stii cum sa creezi module noi si cum sa le integrezi cu altele deja existente.