O aplicație simplă de primăvară folosind adnotarea @autowired

În ultimul post, când am creat o aplicație simplă de primăvară. Pentru a conecta componentele, am folosit un fișier xml de configurare. Dar această abordare cu fișierul xml se bazează pe vechiul stil de primăvară, adică pe izvoarele înainte de timpul de comunicare. În acest post vom ridica aceeași aplicație, numai pentru conectarea fasolei vom folosi adnotări, mai precis adnotarea @Autowired. Toată teoria introductivă despre cum a putut să dezvăluie în postul trecut. în acest lucru voi sublinia doar diferențele de la abordarea de a crea o aplicație sprite care este legat folosind fișierul xml de configurare din aplicația sprinkler care este legat de adnotarea @Autowired.







Deoarece în acest post vorbesc în detaliu despre primăvară, așa că sa dovedit a fi un pic lung, care vrea o scurtă descriere și merge direct la punct, el poate privi în postul de primăvară într-o coajă de nucă

Pentru acest exemplu, avem nevoie de:

Un proiect gata pentru o primă aplicare simplă poate fi descărcat de pe link-ul:

Structura proiectului

După ce adăugăm toate fișierele necesare în aplicație și execută scriptul build.sh, directorul de construire va apărea în directorul curent. cu structura aplicației colectate:

Stilul primăverii

Mai întâi, voi da un exemplu de aplicație simplă de primăvară din postul anterior, când am folosit fișierul xml pentru a conecta componentele:

Figure.java

Circle.java

Rectangle.java

Print.java

Execute.java

Rezumat @Autowired

Toate clasele sunt exact aceleași ca în postul anterior, o simplă cerere de primăvară. În acest post le schimbăm puțin, sau mai degrabă adăugăm ceva. Dar, mai întâi, uitați din nou la fișierul de configurare context.xml din ultimul post, când am ridicat o aplicație simplă de primăvară. Să fim atenți la linia a douăzecea:

context.xml

În această linie, cercul de coș este asociat cu coșul de imprimare. Pentru ca cercul de bin să se asocieze cu coșul de imprimare. am setat cercul pentru bibliotecă. Aceasta înseamnă că dacă eliminăm această linie de legare, atunci va fi lăsată imprimată fără cerc și nu va mai fi nimic de imprimat. Pentru a face coșul de coș încă legat la coșul de imprimare, este posibil să faceți altfel, vom adnota câmpul Figura cu adnotarea @Autowired. și eticheta

(adică linia a douăzecea) este aruncat din fișierul de configurare, adică în momentul în care clasa Print.java arată astfel (cu adnotarea @Autowired adăugată pe a șaptea linie):

Print.java

iar fișierul de configurare context.xml arată astfel:

context.xml

BeanPostProcessor, fasole personalizată și nespecificată (sprint)

În fișierul de configurare context.xml anterior, sunt înregistrate trei fasole, acesta este: cerc. dreptunghi și imprimare. Rețineți că legarea componentelor nu plecat nicăieri, este pur și simplu transferate din fișierul de configurare din clasa Print.java și acum prin adnotare @Autowired (în lista precedentă Print.java linia 7). Deci asta? Nu știu, să vedem. Colectați proiectul cu ./build.sh:

Și ce sa întâmplat? Din ieșire, vedem că fișierele binare au fost create, dar când ați încercat să apelați metoda showSquare (), NPE s-a prăbușit.
Dacă vă uitați atent la această eroare, puteți presupune că metoda showSquare () încearcă să rezolve pointerul la nul. Așa face, în metoda showSquare (). accesați câmpul figura. dar este gol. Acest lucru ar putea însemna că cercul recipientului nu a fost legat automat de coșul de imprimare. Dar ce sa întâmplat? Este adnotarea @Autowired un pic? Se pare că da. De fapt, am indicat adnotarea @Autowired. dar spiritele nu știu nimic despre asta, astfel că fasolele sunt legate automat, trebuie să puneți primăvara pe ea. Primăvara este anunțată cu privire la adnotarea @Autowired adăugând Bina în context

În discuția ulterioară vom presupune că fasolea a inventat și ne-a ridicat această pubele personalizate și pubele de bibliotecă springovoy springovye. Ce am făcut acum? Am adăugat bin springovy (aceasta springovy, nu personalizate) AutowiredAnnotationBeanPostProcessor BeanPostProcessor care implementează interfața și fasole de primăvară creează în primul rând, pentru că este Bina, care a creat alte tipuri de fasole. Adică, mai întâi izvorăsc toate fasolele care implementează interfața BeanPostProcessor. și apoi, la momentul creării și configurarea de primăvară noastre (un obicei) Bina, BeanFactory (BeanFactory este o fabrica care produce fasole) creează un coș personalizat, apoi el (de primăvară), el (bin personalizat) trece pentru procesarea de fasole pune în aplicare interfață BeanPostProcessor în acest caz, l bin AutowiredAnnotationBeanPostProcessor (bin springovy). Încă o dată AutowiredAnnotationBeanPostProcessor bin a fost deja pre-stabilit de primăvară înainte de a fi (de primăvară) a creat un coș de personalizat. În AutowiredAnnotationBeanPostProcessor pus în aplicare logica care caută tot câmpul adnotarea adnotate @Autowired și prin reflekshen le pune ceva, de exemplu, un cos diferit. Apoi, după procesarea unui bin tratat personalizat de fasole procesor de fasole post (deoarece câmpurile prosechenymi) întoarcere de primăvară (sau mai degrabă în BeanFactory), și de primăvară, au un bin gata, se pune într-un recipient.

Am adăugat sprite AutowiredAnnotationBeanPostProcessor. dar procesează numai adnotarea @Autowired. că dacă în clasă avem alte adnotări, de exemplu @Executați sau alții? Totuși, dacă este @ cerut. apoi procesează fasole post-procesor org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor întrebarea cât de mult trebuie să știți diferite procesoare de fasole poștale care urmează să fie incluse în contextul fiecărei adnotare? Pentru a nu trebuie să memoreze toate acestea, și putem adăuga în contextul contextului de utilizare neymspeys: adnotare-config că toate acestea vor face pentru noi. În loc să scrie toate aceste nume lungi de procesoare bin-post în configurație, puteți scrie:

Sub această etichetă, etichetele Ixamel sunt ascunse, care adaugă la context toate procesoarele bin-post necesare, pentru toate adnotările sprint.
Adăugați această etichetă în fișierul de configurare. Fișierul de configurare ar trebui să arate astfel:

context.xml

Rulați din nou ansamblul cu comanda ./build.sh. vedem că binul este ridicat, dar, din nou, se scurge, de această dată BeanCreationException:

Ei bine, nu-i așa? După ce studiați câteva jurnale, puteți acorda atenție acestui mesaj:







Adică, primăvara ne spune că nu știe cu ce bin să asocieze com.devblogs.component.figure.Figure câmpul cu un cerc sau cu un dreptunghi. Totul ar fi bine dacă aveam doar un singur recipient de tip Figura. dar avem doi, ambii sunt de tip trei. Primavara in momentul de fata nu stie cu ce clasa de fasole Print se leaga, asa ca primavara nu a inceput. Pentru ca Spring să poată asocia clasa Print cu orice coș, puteți să eliminați din fișierul de configurare înregistrarea uneia dintre fasole, fie cerc, fie dreptunghi. În acest caz, unul dintre ele va înceta să fie un coș, iar binul care rămâne va deveni singurul coș care este moștenit din Figura și apoi totul va funcționa. Dar nu ne place o astfel de opțiune, pentru că vrem să avem ambele fasole și doar una dintre ele a fost legată de câmpul Figura. Pentru ca primăvara să nu-și strice ce bin el ar trebui să aleagă, trebuie să-i spunem care bin să pună în câmp Figura. Pentru aceasta, este utilizată adnotarea @Qualifier. care spune izvoarelor care ar trebui să i se pună bin în acest câmp. Adăugați adnotarea @Qualifier la clasa Print.java, împreună cu numele fasolei, care este specificată în paranteze cu care Spring va lega câmpul Figura. Acum, clasa Print.java ar trebui să arate astfel:

Print.java

Aici afirmăm că sprinzând folosind adnotarea @Qualifier (linia 9) că cercul de bin ar trebui să fie pus în coala de imprimare. De asemenea, rețineți că clasa Print.java nu are acum o metodă setată pentru câmpul Figura. Nu este pentru că primăvara acum traversează figura câmpului prin reflecție.
Odată ce avem totul in echipa ./build.sh avans tot ceea ce ar trebui să funcționeze fără erori, iar în producția ar trebui să vedem zona cercului, pentru că în metoda de showSquare figura indicator () în cele din urmă găsit în memoria Cercului obiectului:


La fel ca eticheta

adică, pe lângă adăugarea tuturor postprocesoarelor necesare în context, va scana în continuare pachetele pentru adnotarea @Component sau @Service.
Contextul Tag: componenta de scanare scanează un anumit pachet sau un anumit pachete și caută fasole și cele care vor crea. Ce înseamnă asta? Acest lucru înseamnă că, în fișierul de configurare, putem omite definirea explicită a bin trecerea acestei proceduri pe primăvară, inclusiv acele coșuri care necesită parametri constructor, dar un pic mai departe în acest sens, și în timp ce opțiuni construiește fasole cerc și dreptunghi se va inițializa printr-un fișier de configurare, dar putem elimina definiția tipăririi bin din fișierul de configurare. Scoateți imprimare definiția de fasole dintr-un fișier de configurare context.xml și fișierul nostru de configurare ar arata astfel:

context.xml

Acum, fișierul de configurare context.xml conține doar două definiții de fasole și un context: tag-ul de scanare a componentelor.
Acum, cu fișierul de configurare modificat, executați script.sh:

Din rezultatul precedent, puteți vedea că două fasole cerc și dreptunghi au fost create cu succes, dar la etapa de creare a coșului de imprimare. doar cea pe care am aruncat-o din fișierul de configurare, aplicația zafyalilos 🙁. Instrucțiunea NoSuchBeanDefinitionException indică faptul că primăvara nu a putut găsi tipărirea bin în contextul său, dar nu a putut deoarece nu a fost creată. Dar ce înseamnă asta? Un pic mai devreme am scris că, dacă eliminați definiția coșului de gunoi din fișierul de configurare, acesta nu mai este un coș de gunoi. Asta sa întâmplat. Ce zici de etichetă

Nu a forțat proeminentul de primăvară să scaneze pachetul com.devblogs.component (și toate sub pachete) la fasole? Primăvara a răspuns prin scanarea pachetelor, dar nu a găsit nimic acolo. De ce? Să înțelegem mai departe.

@ Adnotări pentru servicii și @Component

Primăvara nu a găsit nici o fasole în pachete deoarece, potrivit izvoarelor (și opinia primăverii este ultima instanță), acestea nu sunt acolo. Să aruncăm o privire la clasa Print.java (înțeleg că am privit-o de mai multe ori astăzi, și încă o dată):

Print.java

Poate cineva să înțeleagă de la el că acesta este un bin sau o componentă a izvoarelor? Aici și de primăvară nu pot, și că acolo nu există adnotări @ Autowired și @ Qualifier încă faptul că este o componentă. Primăvara are nevoie de garanții că aceasta este o componentă. Pentru aceasta, există o adnotare, care se numește @Component sau @Service. Tot ce trebuie să faceți este să adăugați adnotarea @Component înainte de numele clasei.

Adnotarea @Service diferă de adnotarea @Component

Adnotările @Service și @Component sunt interschimbabile. Ambele adnotări spun de primăvară, că clasa peste care poartă este o fasole, care este un candidat pentru detectarea automată în cazul în care contextul fișier de configurare aplicat eticheta: adnotare-config și tag-ul context, auto-scanare: componenta de scanare sau context, tag-ul pur și simplu: componenta de scanare. Diferența dintre ele este doar în ideea utilizării unei clase adnotate. Adnotarea @Service se aplică cel mai bine unei fasole care furnizează servicii altor fasole. @Component este cea mai potrivită pentru fasole. adică acele fasole care furnizează valori de proprietate altor fasole și nu execută codul al cărui rezultat le utilizează și alte fasole. Dar acestea sunt doar recomandări, nimeni nu urmează aceste recomandări în mod rigid, iar în exemplele următoare se va folosi adnotarea @Component. Chiar dacă clasa oferă logică de afaceri. [102]


@Component adnotă clasa ca o componentă pentru izvoare. Adăugați această adnotare chiar la început înainte de numele clasei, astfel încât clasa Print.java să arate astfel:

Print.java

Încercați din nou să asamblați și să infectați aplicația cu comanda ./build.sh:

De data aceasta cererea este rănită fără erori. Acum, despre ceea ce se întâmplă în această etapă. După primăvară a fost găsit contextul: eticheta de scanare a componentelor în fișierul de configurare. începe procesul de căutare a fasolei, peering în fiecare clasă în pachetul care este specificat în etichetă. Să presupunem că primăvara arată în clasa Print.java. În el, el găsește adnotarea @Component. și concluzionează că acesta este bin. Apoi creează instanța și asociază cu el un cerc de bin care a fost creat manual în fișierul de configurare context.xml. De fapt, dacă nu ar fi fost parametrii constructorului, ar fi posibil să nu se definească nimic în fișierul de configurare deloc, ci să se adauge doar o etichetă

și ar fi făcut totul. Mai mult decât atât, chiar și inițializarea parametrilor constructorului poate fi transferată din fișierul de configurare în clasă așa cum am făcut pentru a inițializa proprietatea cifrei.

Adnotare @ Valoare

Această secțiune va fi în plus față de cea anterioară, în practică, inițializarea parametrilor din cadrul claselor nu se face niciodată, această secțiune este mai degrabă dedicată modului în care poți să faci, dar cum să nu o faci. așa că du-te imediat de aici pentru a construi proiectul.
Pentru a transfera parametrii de inițializare constructorului (sau metoda) dintr-un fișier de configurare în sala de clasă în acest scop, două rezumate, unul care suntem deja familiarizați @Autowired. și o altă valoare. Acum, să renunțăm la definițiile rămase din fișierele de configurare context.xml:

și lăsați doar eticheta

acum fișierul de configurare context.xml constă dintr-o singură etichetă de context: component-scan:

context.xml

Deoarece fișierul de configurare este simplificat la o linie

Dar asta nu e tot. Puteți face fără un fișier de configurare și de a folosi un obiect care este creat în metoda AnnotationConfigApplicationContext Mein de aplicare. În acest obiect, este trimis un pachet de la care începe scanarea clasei pentru adnotările @Component și puteți scoate fasolea din acesta. În acest caz, context.xml fișierul de configurare devine inutilă, din moment ce toate se spune să facă, au făcut AnnotationConfigApplicationContext obiect. adică căutarea și crearea fasolei.
Dar, în clasele Java și Circle.java Rectangle.java nu despre parametrii formali adnota @Value adnotare constructor care indică în paranteze valoarea pe care dorim să o constructorului, iar constructorul adnotată cu aproximativ @Autowired. și deoarece am renunțat, de asemenea, la definițiile cercului și a fasolei dreptunghiulare din fișierul de configurare context.xml. atunci trebuie să adnotăm aceste clase cu adnotarea @Component. Clasele modificate Circle.java și Rectangle.java ar trebui să arate astfel:

Circle.java

Rectangle.java

Aici este cazul când transferul întregului fișier de configurare în clasa Java este mai mult un obstacol decât ajuta. Faptul este că, pentru a modifica valoarea parametrilor de constructor trebuie să recompilați din nou proiectul, chiar dacă folosim de primăvară, dimpotrivă să-l evite. Prin urmare, folosim scrierea de configurare în clasa java pentru a demonstra că putem face acest lucru, dar în viață este mai bine să nu faceți acest lucru. Aceasta este, în clasa Java puteți specifica primăvara, că aici trebuie să pună în aplicare un coș diferit, sau că contactul cu această clasă este necesar ca fasole, dar datele de configurare mai bine rezista dincolo de limitele de cod într-un fișier XML separat, în acest caz, datele se vor baza pe un centralizat și dacă trebuie să schimbați ceva, atunci putem intra în fișierul de configurare și tweak ceva acolo și modificările sunt aplicate imediat, fără a recompila.

Punând totul împreună

Ei bine, asta-i tot, acum voi aduce din nou toate clasele cu fișierul de configurare după toate modificările făcute (modificările sunt evidențiate):

Figure.java

Circle.java

Rectangle.java







Trimiteți-le prietenilor: