CodeGym /Blog Java /Aleatoriu /Spring for lazy people Foundation, concepte de bază și ex...
John Squirrels
Nivel
San Francisco

Spring for lazy people Foundation, concepte de bază și exemple cu cod. Partea 2

Publicat în grup
În articolul anterior , am explicat pe scurt ce este primăvara și ce sunt fasolea și contextul. Acum este timpul să-l încerci. O voi face folosind IntelliJ IDEA Enterprise Edition. Dar toate exemplele mele ar trebui să funcționeze și în ediția gratuită a comunității IntelliJ IDEA. În capturi de ecran, dacă vedeți că am o fereastră pe care nu o aveți, nu vă faceți griji — nu este important pentru acest proiect :) În primul rând, Spring for lazy people Foundation, concepte de bază și exemple cu cod.  Partea 2 - 1creați un proiect Maven gol. Am arătat cum se face acest lucru în articolul de la acest link . Citiți până la cuvintele „ Este timpul să ne convertim proiectul Maven într-un proiect web. ” — după aceea, articolul arată cum să facem un proiect web, dar nu avem nevoie de asta acum. În src/main/javafolder, creați un pachet (în cazul meu, l-am numit " en.codegym.info.fatfaggy.animals. Îl puteți numi cum doriți. Nu uitați să înlocuiți numele pachetului meu cu numele pachetului dvs. în toate locurile potrivite. Acum creați clasa Mainși adăugați un metodă

public static void main(String[] args) {
    ...
}
După aceea, deschideți fișierul pom.xml și adăugați secțiunea dependencies. Acum accesați depozitul Maven și găsiți contextul Spring pentru cea mai recentă versiune stabilă. Pune ce găsim în dependenciessecțiune. Am descris acest proces mai detaliat în acest alt articol CodeGym (vezi secțiunea intitulată „ Conectarea dependențelor în Maven ”). Apoi, Maven însuși va găsi și descărca dependențele necesare. În cele din urmă, ar trebui să obțineți ceva de genul acesta: Spring for lazy people Foundation, concepte de bază și exemple cu cod.  Partea 2 - 2în fereastra din stânga, puteți vedea structura proiectului cu pachetul și clasa Main. Fereastra din mijloc arată cum arată pom.xml pentru mine. Am adăugat și o proprietățisecțiune la acesta. Această secțiune îi spune lui Maven ce versiune de Java folosesc în fișierele mele sursă și ce versiune să compilez. Asta pentru ca IDEA să nu mă avertizeze că folosesc o versiune veche de Java. Acest lucru este opțional :) Fereastra din dreapta arată clar că, deși am conectat doar modulul spring-context, acesta a tras automat modulele spring-core, spring-beans, spring-aop și spring-expression. Am fi putut conecta fiecare modul separat, scriind o dependență pentru fiecare modul cu versiunea explicită în fișierul pom.xml, dar deocamdată suntem mulțumiți de lucrurile așa cum sunt. Acum creați entitiespachetul și creați 3 clase în el: Cat, Dog, Parrot. Să dăm fiecărui animal un nume (private String name— puteți codifica unele valori acolo). Getters/setterii sunt publici. Acum trecem la Mainclasa si main()metoda si scriem cam asa:

public static void main(String[] args) {
	// Create an empty Spring context that will look for its own beans based on the annotations in the specified package
	ApplicationContext context = 
		new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.entities");

	Cat cat = context.getBean(Cat.class);
	Dog dog = (Dog) context.getBean("dog");
	Parrot parrot = context.getBean("parrot-polly", Parrot.class);

	System.out.println(cat.getName());
	System.out.println(dog.getName());
	System.out.println(parrot.getName());
}
Mai întâi, creăm un obiect context, spunându-i constructorului în ce pachet să caute pentru a găsi beans. Cu alte cuvinte, Spring va parcurge acest pachet și va încerca să găsească clase marcate cu adnotări speciale care indică că sunt fasole. Apoi creează obiectele acestor clase și le pune în context. După aceea, obținem o pisică din acest context. Facem apel la obiectul context pentru a ne oferi un bean (obiect), indicând clasa obiectului pe care îl dorim (apropo, putem specifica și interfețe, nu doar clase). După aceea, Spring returnează un obiect din clasa solicitată, pe care apoi îl salvăm într-o variabilă. Apoi, îi cerem primăverii să ne aducă o fasole numită „câine”. Când primăvara creează oDogobiect, îi dă obiectului un nume standard (cu excepția cazului în care bean-ului creat i s-a atribuit în mod explicit un nume), care este numele clasei, dar cu o literă inițială minusculă. În acest caz, clasa noastră se numește Dog, așa că numele bobului este „câine”. Dacă avem nevoie de un BufferedReaderobiect acolo, atunci Spring l-ar numi „bufferedReader”. Și pentru că Java nu poate fi sigur 100% ce clasă vrem, returnează un Objectobiect, pe care apoi îl aruncăm manual la tipul dorit, adicăDog. Opțiunea în care clasa este indicată în mod explicit este mai convenabilă. A treia opțiune este să obțineți un bean după numele clasei și după numele beanului. Este posibil ca contextul să aibă mai multe fasole dintr-o singură clasă. Pentru a indica boabele de care avem nevoie, indicăm numele acestuia. Deoarece indicăm și în mod explicit clasa aici, nu mai trebuie să facem o distribuție. IMPORTANT!Dacă Spring găsește mai multe boabe care se potrivesc cerințelor noastre, atunci nu poate determina ce boabe să ne ofere, așa că va face o excepție. Prin urmare, pentru a evita această situație, ar trebui să încercați să fiți cât mai specific posibil în a-i spune lui Spring de ce bob aveți nevoie. Dacă Spring caută contextul său și nu reușește să găsească un singur bean care să corespundă cerințelor noastre, atunci va arunca și o excepție. În cele din urmă, pur și simplu afișăm numele animalelor noastre pentru a verifica dacă avem cu adevărat obiectele de care avem nevoie. Dar dacă rulăm programul acum, vom vedea că primăvara este nefericită - nu poate găsi animalele de care avem nevoie în contextul său. Acest lucru se datorează faptului că nu a creat aceste fasole. După cum am spus anterior, atunci când Spring scanează clasele, își caută propriile adnotări Spring. Și dacă Spring nu găsește aceste adnotări, atunci nu găsește Nu cred că aceste clase corespund fasolelor pe care trebuie să le creeze. Remedierea acestui lucru necesită pur și simplu adăugarea@Componentadnotare în fața fiecăreia dintre clasele noastre de animale.

@Component
public class Cat {
	private String name = "Oscar";
	...
}
Dar mai sunt. Dacă trebuie să îi spunem explicit lui Spring că bean-ul pentru această clasă ar trebui să aibă un nume specific, indicăm numele între paranteze după adnotare. De exemplu, pentru a-i spune lui Spring să dea numele „ parrot-polly” fasolei papagal, care este numele pe care îl vom folosi pentru a obține acest papagal în metodă main, ar trebui să facem ceva de genul:

@Component("parrot-polly")
public class Parrot {
	private String name = "Polly";
	...
}
Acesta este punctul central al configurației automate . Îți scrii cursurile, le marchezi cu adnotările necesare și îi spui lui Spring pachetul care conține clasele tale. Acesta este pachetul prin care framework-ul va rula pentru a găsi adnotări și pentru a crea obiecte din aceste clase. Apropo, Spring nu caută doar @Componentadnotări, ci și toate celelalte adnotări care o moștenesc pe aceasta. De exemplu, @Controller, @RestController, @Service, @Repository, și altele, pe care le vom introduce în articolele viitoare. Acum vom încerca să facem același lucru folosind configurația bazată pe Java . Pentru a începe, eliminați@Componentadnotări de la cursurile noastre. Pentru a face lucrurile mai provocatoare, imaginați-vă că nu am scris aceste clase, așa că nu le putem modifica cu ușurință, ceea ce înseamnă că nu putem adăuga adnotări. Este ca și cum aceste clase sunt ambalate într-o bibliotecă. În acest caz, nu avem nicio modalitate de a edita aceste clase astfel încât să fie recunoscute de Spring. Dar avem nevoie de obiecte din aceste clase! Aici avem nevoie de configurație bazată pe Java pentru a crea obiectele. Pentru a începe, creați un pachet cu un nume precum configs. În acest pachet, creați o clasă Java obișnuită, ceva de genul MyConfig, și marcați-o cu @Configurationadnotarea.

@Configuration
public class MyConfig {
}
Acum trebuie să modificăm main()metoda, schimbând modul în care creăm contextul. Putem fie să indicăm în mod explicit care clasă are configurația noastră:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Dacă avem mai multe clase diferite care creează fasole și dorim să conectăm mai multe dintre ele simultan, pur și simplu le indicăm pe toate acolo, separate prin virgule:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
Și dacă avem prea multe dintre ele și vrem să le conectăm pe toate simultan, atunci pur și simplu indicăm numele pachetului în care sunt conținute:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.configs");
În acest caz, Spring va parcurge pachetul și va găsi toate clasele marcate cu adnotare @Configuration. Ei bine, și dacă avem un program foarte mare în care configurațiile sunt împărțite în diferite pachete, atunci pur și simplu indicăm o listă delimitată prin virgulă de nume ale pachetelor care conțin configurațiile:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.database.configs",
		"en.codegym.info.fatfaggy.animals.root.configs",
		"en.codegym.info.fatfaggy.animals.web.configs");
Sau numele unui pachet care este comun pentru toți:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals");
O puteți face oricum doriți, dar mi se pare că prima opțiune, care indică pur și simplu o clasă cu configurațiile, se va potrivi cel mai bine programului nostru. Când creează un context, Spring caută clase marcate cu @Configurationadnotare și își va crea propriile obiecte ale acestor clase. Încearcă să apeleze metode marcate cu @Beanadnotare, ceea ce înseamnă că aceste metode returnează fasole (obiecte) pe care Spring le va adăuga contextului. Și acum vom crea fasole pentru o pisică, un câine și un papagal din clasa noastră cu configurație bazată pe Java. Acest lucru este destul de simplu de făcut:

@Bean
public Cat getCat() {
	return new Cat();
}
Aici creăm manual pisica noastră și o dăm lui Spring, care apoi ține obiectul nostru în contextul său. Deoarece nu am dat în mod explicit un nume bobului nostru, Spring îi va da același nume ca și numele metodei. În cazul nostru, fasolea pisicii se va numi " getCat". Dar pentru că folosim clasa, nu numele, pentru a introduce boabele de pisică în mainmetodă, numele bobului nu este important pentru noi. În mod similar, creați o fasole de câine, ținând cont că Spring va da numele metodei fasolei. Pentru a numi în mod explicit fasolea papagalului nostru, pur și simplu îi indicăm numele între paranteze după @Beanadnotare:

@Bean("parrot-polly")
public Object weNeedMoreParrots() {
	return new Parrot();
}
După cum puteți vedea, aici am indicat un Objecttip de returnare și am dat metodei un nume arbitrar. Acest lucru nu afectează numele bobului, deoarece am specificat în mod explicit numele aici. Totuși, este mai bine să indicați o valoare de returnare mai mult sau mai puțin semnificativă și un nume de metodă. Fă asta dacă nu din alt motiv decât să-ți faci o favoare atunci când redeschizi proiectul într-un an. :) Acum luați în considerare situația în care avem nevoie de un bob pentru a crea un alt bob . De exemplu, să presupunem că dorim ca numele pisicii din fasolea pisicii să fie numele papagalului plus șirul „-killer”. Nici o problemă!

@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
Aici Spring va vedea că pentru a crea acest bob, cadrul trebuie să treacă în fasolea papagal creată anterior. În consecință, va aranja lanțul necesar de apeluri de metodă: mai întâi, este apelată metoda de creare a papagalului și apoi cadrul trece noul papagal la metoda de creare a pisicilor. Iată unde intervine injecția de dependență : Spring în sine transmite boabele de papagal necesare metodei noastre. Dacă IDEA se supără din cauza parrotvariabilei, nu uitați să schimbați tipul de returnare al metodei de creare a papagalilor de la Objectla Parrot. În plus, configurația bazată pe Java vă permite să rulați absolut orice cod Javaîn metodele tale de a crea fasole. Puteți face orice: creați alte obiecte auxiliare, apelați orice alte metode, chiar și cele care nu sunt marcate cu adnotări Spring, creați bucle, condiții booleene - orice vă vine în minte! Acest lucru nu este posibil cu configurarea automată și cu atât mai puțin cu configurarea XML. Acum să luăm în considerare o problemă care este puțin mai distractivă. Polimorfism și interfețe :) Vom crea o WeekDayinterfață și vom crea 7 clase care implementează această interfață: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. Vom oferi interfeței o String getWeekDayName()metodă, care va returna numele zilei săptămânii pentru clasa corespunzătoare. Cu alte cuvinte, Mondayclasa va reveni "Monday", etc. La pornirea aplicației, să presupunem că sarcina noastră este să punem în context un bean corespunzător zilei curente a săptămânii. Nu bean-uri pentru toate clasele care implementează interfața - doar un bean de care avem nevoie. WeekDayPuteți face asta cam asa:

@Bean
public WeekDay getDay() {
	DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
	switch (dayOfWeek) {
		case MONDAY: return new Monday();
		case TUESDAY: return new Tuesday();
		case WEDNESDAY: return new Wednesday();
		case THURSDAY: return new Thursday();
		case FRIDAY: return new Friday();
		case SATURDAY: return new Saturday();
		default: return new Sunday();
	}
}
Aici tipul de returnare este interfața noastră. Metoda returnează un obiect de bună credință al uneia dintre clasele care implementează interfața, în funcție de ziua curentă a săptămânii. Acum putem face următoarele în main()metodă:

WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("Today is " + weekDay.getWeekDayName() + "!");
Pentru mine, programul îmi spune că este duminică :) Sunt încrezător că dacă rulez programul mâine, contextul va conține un cu totul alt obiect. Rețineți că obținem bean-ul pur și simplu folosind interfața: context.getBean(WeekDay.class). Spring va căuta în contextul său bean-ul care implementează interfața și îl va returna. Apoi se dovedește că WeekDayvariabila noastră se termină cu un obiect de duminică, iar conceptul familiar de polimorfism se aplică pe măsură ce lucrăm cu această variabilă. :) Acum câteva cuvinte despre abordarea combinată , în care unele bean-uri sunt create automat de Spring, unele prin scanarea pachetelor pentru clase cu adnotare @Component, iar altele prin configurație bazată pe Java. Pe măsură ce luăm în considerare acest lucru, vom reveni la versiunea originală, unde Cat, Dog, șiParrotorele au fost marcate cu @Componentadnotare. Să presupunem că vrem să creăm fasole pentru animalele noastre prin ca Spring să scaneze automat pachetul entities, dar vrem să creăm și o fasole cu ziua săptămânii, așa cum tocmai am făcut-o. Tot ce trebuie să faceți este să adăugați @ComponentScanadnotarea la nivelul clasei MyConfig, pe care o indicăm la crearea contextului în main(), și să indicați între paranteze pachetul care trebuie scanat și să creați automat bean-uri din clasele necesare:

@Configuration
@ComponentScan("en.codegym.info.fatfaggy.animals.entities")
public class MyConfig {
	@Bean
	public WeekDay getDay() {
		DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
		switch (dayOfWeek) {
			case MONDAY: return new Monday();
			case TUESDAY: return new Tuesday();
			case WEDNESDAY: return new Wednesday();
			case THURSDAY: return new Thursday();
			case FRIDAY: return new Friday();
			case SATURDAY: return new Saturday();
			default: return new Sunday();
		}
	}
}
Când creează contextul, Spring vede că trebuie să proceseze MyConfigclasa. Intră în clasă și vede că trebuie să scaneze en.codegym.info.fatfaggy.animals.entitiespachetul „ ” și să creeze bean-uri ale acelor clase, după care execută metoda MyConfigclasei getDay()și adaugă un WeekDaybean în context. În main()metodă, avem acum acces la toate boabele de care avem nevoie: atât obiecte animale, cât și o fasole cu ziua săptămânii. Dacă vreodată trebuie să faceți ca Spring să ridice și câteva fișiere de configurare XML, puteți face propria căutare pe web pentru a găsi o explicație :) Rezumat:
  • Încercați să utilizați configurația automată
  • În timpul configurării automate, indicați numele pachetului care conține clasele ale căror bean-uri trebuie create
  • Aceste clase sunt marcate cu @Componentadnotare
  • Spring parcurge toate aceste clase, creează obiecte și le pune în context;
  • Dacă configurarea automată nu ne convine din anumite motive, folosim configurația bazată pe Java
  • În acest caz, creăm o clasă Java obișnuită ale cărei metode returnează obiectele de care avem nevoie. Marcam această clasă cu @Configurationadnotarea dacă vom scana întregul pachet, mai degrabă decât să indicăm o anumită clasă cu configurația atunci când creăm contextul
  • Metodele acestei clase care returnează boabe sunt marcate cu @Beanadnotare
  • Dacă dorim să activăm scanarea automată atunci când folosim configurația bazată pe Java, folosim adnotarea @ComponentScan.
Dacă acest articol a fost complet confuz, atunci încercați să-l citiți în câteva zile. Sau dacă sunteți la unul dintre primele niveluri ale CodeGym, poate fi puțin devreme să studiați Primăvara. Puteți reveni oricând la acest articol puțin mai târziu, când vă simțiți mai încrezători în abilitățile dumneavoastră de programare Java. Dacă totul este clar, atunci puteți încerca să convertiți un proiect al dvs. de companie în Spring :) Dacă unele lucruri sunt clare, dar altele nu sunt, atunci vă rugăm să lăsați un comentariu :) Spune-mi sugestiile și criticile tale, dacă am greșit undeva sau am scris niște prostii :) În următorul articol, ne vom scufunda brusc în spring-web-mvc și vom face o aplicație web simplă folosind Spring.
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION