JavaRush /Java Blog /Random-IT /La primavera è per i pigri. Fondamenti, concetti di base ...
Стас Пасинков
Livello 26
Киев

La primavera è per i pigri. Fondamenti, concetti di base ed esempi con codice. Parte 2

Pubblicato nel gruppo Random-IT
Nello scorso articolo ho spiegato in poche parole cos'è la primavera, cosa sono i bidoni e il contesto. Ora è il momento di provare come funziona il tutto. La primavera è per i pigri.  Fondamenti, concetti di base ed esempi con codice.  Parte 2 - 1Lo farò io stesso in Intellij Idea Enterprise Edition. Ma tutti i miei esempi dovrebbero funzionare anche nella versione gratuita di Intellij Idea Community. Se negli screenshot vedi che ho una sorta di finestra che tu non hai, non preoccuparti, non è fondamentale per questo progetto :) Innanzitutto, creiamo un progetto Maven vuoto. Ho mostrato come farlo nell'articolo (leggi fino alle parole " È ora di trasformare il nostro progetto Maven in un progetto web. ", dopodiché mostra già come creare un progetto web e non ne abbiamo bisogno ora) Creiamolo nella cartella src/main /java è un pacchetto (nel mio caso l'ho chiamato " ru.javarush.info.fatfaggy.animals", puoi chiamarlo come vuoi, ma non dimenticare di sostituirlo con il tuo nome nei posti giusti). E creiamo una classe Mainin cui creeremo un metodo
public static void main(String[] args) {
    ...
}
Quindi apri il file pom.xml e aggiungi una sezione lì dependencies. Ora andiamo al repository Maven e cerchiamo lì il contesto primaverile dell'ultima versione stabile e incolliamo quello che abbiamo ottenuto nella sezione dependencies. Ho descritto questo processo in modo un po' più dettagliato in questo articolo (vedere la sezione " Connessione delle dipendenze in Maven "). Quindi Maven stesso troverà e scaricherà le dipendenze necessarie e alla fine dovresti ottenere qualcosa del genere:
La primavera è per i pigri.  Fondamenti, concetti di base ed esempi con codice.  Parte 2 - 2
Nella finestra di sinistra puoi vedere la struttura del progetto con il pacchetto e la classe Main. La finestra centrale mostra come appare il mio pom.xml. Ho anche aggiunto lì una sezione delle proprietà , in cui ho indicato a Maven quale versione di Java stavo utilizzando nel codice sorgente e in quale versione compilare. Questo solo per non farmi venire l'idea di un avviso all'avvio che indica che viene utilizzata una vecchia versione di Java. Puoi farlo, non puoi) Nella finestra di destra - puoi vedere che anche se abbiamo collegato solo il contesto primaverile - ha aggiunto automaticamente core, bean, aop ed espressione. Era possibile collegare ogni modulo separatamente, registrando per ciascuno una dipendenza in memoria con l'indicazione esplicita della versione, ma per ora ci accontentiamo dell'opzione così com'è. Ora creiamo un pacchetto entities(entità) e creiamo 3 classi al suo interno: Cat, Dog, Parrot. Lascia che ogni animale abbia un nome ( private String name, puoi codificare alcuni valori lì) e i getter/setter sono pubblici. Ora vai in classe Maine main()scrivi qualcosa di simile nel metodo:
public static void main(String[] args) {
	// create an empty spring context that will search for its beans by annotations in the specified package
	ApplicationContext context =
		new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.entities");

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

	System.out.println(cat.getName());
	System.out.println(dog.getName());
	System.out.println(parrot.getName());
}
Per prima cosa creiamo un oggetto di contesto e nel costruttore gli diamo il nome del pacchetto che deve essere scansionato per la presenza di bean. Cioè, Spring esaminerà questo pacchetto e proverà a trovare classi contrassegnate con annotazioni speciali che facciano sapere a Spring che si tratta di un bean. Dopodiché crea oggetti di queste classi e li inserisce nel suo contesto. Dopodiché otteniamo un gatto da questo contesto. Quando ci rivolgiamo all'oggetto contesto, gli chiediamo di fornirci un bean (oggetto) e di indicare di quale classe di oggetto abbiamo bisogno (qui, tra l'altro, puoi specificare non solo le classi, ma anche le interfacce). Dopodiché Spring ci restituisce un oggetto di questa classe, che salviamo in una variabile. Successivamente, chiediamo a Spring di procurarci un fagiolo chiamato “cane”. Quando Spring crea un oggetto classe, Doggli assegnerà un nome standard (se il nome del bean in creazione non è specificato esplicitamente), che è il nome della classe dell'oggetto, solo con una lettera minuscola. Pertanto, poiché la nostra classe si chiama Dog, il nome di tale fagiolo sarà “cane”. Se avessimo un oggetto lì BufferedReader, Spring gli darebbe il nome predefinito "bufferedReader". E poiché in questo caso (in Java) non esiste la certezza esatta di quale classe sarà un tale oggetto, ne verrà semplicemente restituito uno specifico Object, che poi trasformeremo manualmente nel tipo di cui abbiamo bisogno Dog. Più conveniente l'opzione con l'indicazione esplicita della classe. Ebbene, nel terzo caso, otteniamo un bean per classe e nome. Potrebbe semplicemente esserci una situazione in cui nel contesto saranno presenti più bean della stessa classe e per indicare di quale particolare bean abbiamo bisogno, ne indichiamo il nome. Poiché anche qui abbiamo indicato chiaramente la classe, non dobbiamo più lanciare. Importante!Se si scopre che Spring trova diversi bean in base ai requisiti che le abbiamo specificato, non sarà in grado di determinare quale bean darci e lancerà un'eccezione. Cercate quindi di indicargli nel modo più preciso possibile di quale contenitore avete bisogno, in modo che non si verifichino situazioni del genere. Se Spring non trova un singolo bean nel suo contesto in base alle tue condizioni, genererà anche un'eccezione. Bene, allora mostriamo semplicemente i nomi dei nostri animali sullo schermo per assicurarci che questi siano effettivamente esattamente gli oggetti di cui abbiamo bisogno. Ma se eseguiamo il programma adesso, vedremo che Spring giura di non riuscire a trovare gli animali di cui abbiamo bisogno nel suo contesto. Ciò è accaduto perché non ha creato questi fagioli. Come ho già detto, quando Spring scansiona le lezioni, cerca lì le “sue” annotazioni Spring. E se non lo trova, allora non percepisce classi come quelle di cui ha bisogno di creare i fagioli. Per risolvere questo problema, aggiungi semplicemente un'annotazione @Componentdavanti alla classe nelle nostre classi di animali.
@Component
public class Cat {
	private String name = "Barsik";
	...
}
Ma non è tutto. Se dobbiamo indicare esplicitamente a Spring che il bean per questa classe deve avere un nome specifico, tale nome può essere indicato tra parentesi dopo l'annotazione. Ad esempio, affinché Spring dia il nome di cui abbiamo bisogno parrot-keshaal cestino dei pappagalli, da cui mainpoi riceveremo questo pappagallo, dobbiamo fare qualcosa del genere:
@Component("parrot-kesha")
public class Parrot {
	private String name = "Kesha";
	...
}
Questo è il punto centrale della configurazione automatica . Scrivi le tue classi, contrassegnale con le annotazioni necessarie e indichi a Spring un pacchetto con le tue classi, attraverso il quale passa, cerca annotazioni e crea oggetti di tali classi. A proposito, Spring cercherà non solo le annotazioni @Component, ma anche tutte le altre annotazioni ereditate da questa. Ad esempio, @Controller, @RestController, @Service, @Repositorye altri, che incontreremo in ulteriori articoli. Ora proviamo a fare lo stesso, ma utilizzando la configurazione Java . Innanzitutto, rimuoviamo le annotazioni @Componentdalle nostre classi. Per complicare il compito, immaginiamo che queste non siano classi scritte da noi, che possiamo facilmente modificare, aggiungere qualcosa, comprese le annotazioni. È come se queste lezioni fossero stipate in una biblioteca. In questo caso non possiamo modificare in alcun modo queste classi in modo che vengano accettate da Spring. Ma abbiamo bisogno di oggetti di queste classi! Qui avremo bisogno della configurazione Java per creare tali oggetti. Per cominciare, creiamo un pacchetto, ad esempio configs, e al suo interno - una normale classe Java, ad esempio, MyConfige contrassegniamolo con un'annotazione@Configuration
@Configuration
public class MyConfig {
}
Ora dobbiamo modificare leggermente main()il modo in cui creiamo il contesto nel metodo. Possiamo specificare direttamente la nostra classe con la configurazione lì:
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Se abbiamo più classi diverse in cui creiamo bean e vogliamo collegarne più di una contemporaneamente, li indicheremo semplicemente separati da virgole:
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
Bene, se ne abbiamo troppi e vogliamo collegarli tutti in una volta, indichiamo semplicemente qui il nome del pacchetto in cui li abbiamo:
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.configs");
In questo caso, Spring esaminerà questo pacchetto e troverà tutte le classi contrassegnate con l'annotazione @Configuration. Ebbene, nel caso in cui abbiamo un programma davvero grande dove le config sono divise in diversi pacchetti, indichiamo semplicemente i nomi dei pacchetti con le config separate da virgole:
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.database.configs",
		"ru.javarush.info.fatfaggy.animals.root.configs",
		"ru.javarush.info.fatfaggy.animals.web.configs");
Bene, o il nome di un pacchetto più comune a tutti:
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals");
Puoi farlo come desideri, ma mi sembra che la primissima opzione, in cui specifichi semplicemente una classe con le configurazioni, si adatterà meglio al nostro programma. Durante la creazione di un contesto, Spring cercherà le classi contrassegnate dall'annotazione @Configuratione creerà autonomamente gli oggetti di queste classi. Dopodiché proverà a chiamare i metodi di queste classi contrassegnati con l'annotazione @Bean, il che significa che tali metodi restituiranno i bean (oggetti) che ha già inserito nel suo contesto. Bene, ora creiamo fagioli per gatti, cani e pappagalli nella nostra classe con la configurazione Java. Questo viene fatto in modo molto semplice:
@Bean
public Cat getCat() {
	return new Cat();
}
Si scopre che abbiamo creato noi stessi manualmente il nostro gatto e lo abbiamo dato a Spring, e lui ha già inserito questo nostro oggetto nel suo contesto. Dato che non abbiamo specificato esplicitamente il nome del nostro bean, Spring darà al bean lo stesso nome del nome del metodo. Nel nostro caso il fagiolo del gatto avrà il nome " getCat". Ma poiché in main-e otteniamo ancora il gatto non per nome, ma per classe, in questo caso il nome di questo contenitore non è importante per noi. Crea un fagiolo con un cane allo stesso modo, ma tieni presente che la primavera chiamerà tale fagiolo con il nome del metodo. Per denominare esplicitamente il nostro fagiolo con il pappagallo, è sufficiente indicare il suo nome tra parentesi dopo l'annotazione @Bean:
@Bean("parrot-kesha")
public Object weNeedMoreParrots() {
	return new Parrot();
}
Come puoi vedere, qui ho indicato il tipo del valore restituito Objecte ho chiamato il metodo in qualsiasi modo. Ciò non influisce in alcun modo sul nome del bean perché lo impostiamo esplicitamente qui. Ma è meglio indicare il tipo di valore restituito e il nome del metodo non a caso, ma in modo più o meno chiaro. Anche solo per te stesso, quando aprirai questo progetto tra un anno. :) Ora consideriamo una situazione in cui per creare un bean dobbiamo utilizzare un altro bean . Ad esempio, vogliamo che il nome del gatto nel cat bean sia composto dal nome del pappagallo e dalla stringa "-killer". Nessun problema!
@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
Qui Spring vedrà che prima di creare questo fagiolo, dovrà trasferire qui il fagiolo pappagallo già creato. Pertanto, creerà una catena di chiamate ai nostri metodi in modo che venga chiamato prima il metodo per creare un pappagallo, quindi passa questo pappagallo al metodo per creare un gatto. È qui che ha funzionato la cosa chiamata iniezione delle dipendenze : Spring stessa ha passato il parrot bean richiesto al nostro metodo. Se l'idea si lamenta di una variabile parrot, non dimenticare di modificare il tipo di ritorno nel metodo per creare un pappagallo da Objecta Parrot. Inoltre, la configurazione Java consente di eseguire assolutamente qualsiasi codice Java nei metodi per la creazione di bean. Puoi davvero fare qualsiasi cosa: creare altri oggetti ausiliari, chiamare qualsiasi altro metodo, anche quelli non contrassegnati con annotazioni primaverili, creare loop, condizioni - qualunque cosa ti venga in mente! Tutto ciò non può essere ottenuto utilizzando la configurazione automatica, tanto meno utilizzando le configurazioni xml. Ora diamo un'occhiata a un problema più divertente. Con polimorfismo e interfacce :) Creiamo un'interfaccia WeekDaye creiamo 7 classi che implementerebbero questa interfaccia: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. Creiamo un metodo nell'interfaccia String getWeekDayName()che restituisca il nome del giorno della settimana della classe corrispondente. Cioè, la classe Mondayrestituirebbe " monday", ecc. Diciamo che il compito quando si avvia la nostra applicazione è posizionare un fagiolo nel contesto che corrisponderebbe al giorno corrente della settimana. Non tutti i bean di tutte le classi che implementano WeekDayl'interfaccia, ma solo quello di cui abbiamo bisogno. Si può fare qualcosa del genere:
@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();
	}
}
Qui il tipo di valore restituito è la nostra interfaccia e il metodo restituisce oggetti reali delle classi di implementazione dell'interfaccia a seconda del giorno corrente della settimana. Ora nel metodo main()possiamo fare questo:
WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("It's " + weekDay.getWeekDayName() + " today!");
Mi ha detto che oggi è domenica :) Sono sicuro che se eseguo il programma domani, nel contesto apparirà un oggetto completamente diverso. Tieni presente che qui otteniamo il bean semplicemente dall'interfaccia: context.getBean(WeekDay.class). Spring guarderà nel suo contesto per vedere quale dei suoi bean implementa tale interfaccia e lo restituirà. Bene, allora si scopre che WeekDayesiste un oggetto di tipo in una variabile di tipo Sundaye il polimorfismo, già familiare a tutti noi, inizia quando si lavora con questa variabile. :) E qualche parola sull'approccio combinato , in cui alcuni bean vengono creati dalla stessa Spring, utilizzando la scansione dei pacchetti per la presenza di classi con un'annotazione @Component, e alcuni altri bean vengono creati utilizzando la configurazione Java. Per fare questo, torniamo alla versione originale, quando le classi Cat, Doged Parroterano contrassegnate da un'annotazione @Component. Diciamo che vogliamo creare dei contenitori per i nostri animali utilizzando la scansione automatica del pacco entitiesentro la primavera, ma creiamo un contenitore con il giorno della settimana come abbiamo appena fatto. Tutto quello che devi fare è aggiungere a livello di classe MyConfig, che specifichiamo durante la creazione del contesto mainnell'annotazione -esima @ComponentScan, e indicare tra parentesi il pacchetto che deve essere scansionato e i bean delle classi necessarie create automaticamente:
@Configuration
@ComponentScan("ru.javarush.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();
		}
	}
}
Si scopre che quando si crea un contesto, Spring vede che è necessario elaborare la classe MyConfig. Ci entra e vede che deve scansionare il pacchetto " ru.javarush.info.fatfaggy.animals.entities" e creare bean di quelle classi, dopodiché esegue un metodo getDay()dalla classe MyConfige aggiunge un bean del tipo WeekDayal suo contesto. Nel metodo, main()ora abbiamo accesso a tutti i fagioli di cui abbiamo bisogno: sia gli oggetti animali che il fagiolo del giorno della settimana. Come assicurarti che Spring raccolga anche alcune configurazioni xml: cercale tu stesso su Internet se ne hai bisogno :) Riepilogo:
  • prova ad usare la configurazione automatica;
  • durante la configurazione automatica indichiamo il nome del pacchetto contenente le classi di cui creare i bean;
  • tali classi sono contrassegnate da un'annotazione@Component;
  • la primavera attraversa tutte queste classi e crea i loro oggetti e li colloca nel contesto;
  • se per qualche motivo la configurazione automatica non ci soddisfa, utilizziamo la configurazione Java;
  • in questo caso, creiamo una normale classe Java i cui metodi restituiranno gli oggetti di cui abbiamo bisogno e contrassegniamo tale classe con un'annotazione @Configurationnel caso in cui scansioniamo l'intero pacchetto anziché specificare una classe specifica con configurazione durante la creazione del contesto;
  • i metodi di questa classe che restituiscono bean sono contrassegnati con l'annotazione @Bean;
  • se vogliamo abilitare la scansione automatica quando utilizziamo la configurazione Java, utilizziamo l'annotazione @ComponentScan.
Se nulla è chiaro, prova a leggere questo articolo tra un paio di giorni. Bene, o se sei ai primi livelli di Javarash, forse è un po' presto per imparare la primavera. Puoi sempre tornare a questo articolo un po' più tardi, quando ti sentirai più sicuro nella programmazione in Java. Se è tutto chiaro, puoi provare a trasferire alcuni dei tuoi progetti preferiti in Spring :) Se qualcosa è chiaro, ma qualcosa non è così tanto, commenta :) Ci sono anche suggerimenti e commenti se ho fatto un passo da qualche parte o ho scritto qualcosa di stupido ) Nel prossimo articolo approfondiremo spring-web-mvc e creeremo una semplice applicazione web utilizzando spring.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION