CodeGym /Java Blog /Random-IT /Primavera per pigri Fondazione, concetti di base ed esemp...
John Squirrels
Livello 41
San Francisco

Primavera per pigri Fondazione, concetti di base ed esempi con codice. Parte 2

Pubblicato nel gruppo Random-IT
Nel precedente articolo ho spiegato brevemente cos'è la Primavera e cosa sono i fagioli e il contesto. Ora è il momento di provarlo. Lo farò usando IntelliJ IDEA Enterprise Edition. Ma tutti i miei esempi dovrebbero funzionare anche nella IntelliJ IDEA Community Edition gratuita. Negli screenshot, se vedi che ho una finestra che tu non hai, non preoccuparti: non è importante per questo progetto :) Per Primavera per pigri Fondazione, concetti di base ed esempi con codice.  Parte 2 - 1prima cosa, crea un progetto Maven vuoto. Ho mostrato come farlo nell'articolo a questo link . Leggi fino alle parole " È tempo per noi di convertire il nostro progetto Maven in un progetto web ". Dopodiché, l'articolo mostra come realizzare un progetto web, ma non ne abbiamo bisogno in questo momento. Nel file src/main/javacartella, crea un pacchetto (nel mio caso l'ho chiamato " en.codegym.info.fatfaggy.animals. Puoi chiamarlo come vuoi. Non dimenticare di sostituire il nome del mio pacchetto con il nome del tuo pacchetto in tutti i posti giusti. Ora crea la Mainclasse e aggiungi un metodo

public static void main(String[] args) {
    ...
}
Successivamente, apri il file pom.xml e aggiungi la dependenciessezione. Ora vai al repository Maven e trova il contesto Spring per l'ultima versione stabile. Metti ciò che troviamo nella dependenciessezione. Ho descritto questo processo in modo più dettagliato in questo altro articolo di CodeGym (vedere la sezione intitolata " Connessione delle dipendenze in Maven "). Quindi Maven stesso troverà e scaricherà le dipendenze necessarie. Alla fine, dovresti ottenere qualcosa del genere: Primavera per pigri Fondazione, concetti di base ed esempi con codice.  Parte 2 - 2Nella finestra a sinistra, puoi vedere la struttura del progetto con il pacchetto e la Mainclasse. La finestra centrale mostra come mi cerca pom.xml. Ho anche aggiunto un propertiessezione ad esso. Questa sezione indica a Maven quale versione di Java sto usando nei miei file sorgente e quale versione compilare. Questo è solo per evitare che IDEA mi avverta che sto usando una vecchia versione di Java. Questo è facoltativo :) La finestra a destra chiarisce che anche se abbiamo collegato solo il modulo spring-context, ha automaticamente inserito i moduli spring-core, spring-beans, spring-aop e spring-expression. Avremmo potuto collegare ogni modulo separatamente, scrivendo una dipendenza per ogni modulo con la versione esplicita nel file pom.xml, ma per ora siamo contenti delle cose come stanno. Ora crea il entitiespacchetto e crea 3 classi in esso: Cat, Dog, Parrot. Diamo ad ogni animale un nome (private String name- puoi codificare alcuni valori lì). I getter/setter sono pubblici. Ora passiamo alla Mainclasse e al main()metodo, e scriviamo qualcosa del genere:

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());
}
Per prima cosa, creiamo un oggetto di contesto, dicendo al costruttore in quale pacchetto cercare per trovare i bean. In altre parole, Spring esaminerà questo pacchetto e cercherà di trovare le classi contrassegnate con annotazioni speciali che indicano che sono bean. Quindi crea gli oggetti di queste classi e li inserisce nel contesto. Dopodiché, otteniamo un gatto da questo contesto. Invochiamo l'oggetto contesto per darci un bean (oggetto), indicando la classe dell'oggetto che vogliamo (a proposito, possiamo anche specificare interfacce, non solo classi). Successivamente, Spring restituisce un oggetto della classe richiesta, che poi salviamo in una variabile. Successivamente, chiediamo a Spring di procurarci un fagiolo chiamato "cane". Quando la primavera crea unDogobject, assegna all'oggetto un nome standard (a meno che al bean creato non sia stato esplicitamente assegnato un nome), che è il nome della classe ma con una lettera iniziale minuscola. In questo caso, la nostra classe si chiama Dog, quindi il nome del bean è be "dog". Se avessimo bisogno di un BufferedReaderoggetto lì, Spring lo chiamerebbe "bufferedReader". E poiché Java non può essere sicuro al 100% di quale classe vogliamo, restituisce un Objectoggetto, che poi trasmettiamo manualmente al tipo desiderato, ad es.Dog. L'opzione in cui la classe è indicata in modo esplicito è più comoda. La terza opzione è ottenere un bean in base al nome della classe e al nome del bean. È possibile che il contesto contenga diversi bean di una singola classe. Per indicare il particolare chicco di cui abbiamo bisogno, ne indichiamo il nome. Poiché anche qui indichiamo esplicitamente la classe, non dobbiamo più eseguire un cast. IMPORTANTE!Se Spring trova diversi bean che soddisfano i nostri requisiti, non può determinare quale bean darci, quindi genererà un'eccezione. Di conseguenza, per evitare questa situazione, dovresti cercare di essere il più specifico possibile nel dire a Spring di quale fagiolo hai bisogno. Se Spring cerca nel suo contesto e non riesce a trovare un singolo bean che soddisfi i nostri requisiti, genererà anche un'eccezione. Infine, mostriamo semplicemente i nomi dei nostri animali per verificare che abbiamo davvero gli oggetti di cui abbiamo bisogno. Ma se eseguiamo il programma ora, vedremo che Spring è infelice: non riesce a trovare gli animali di cui abbiamo bisogno nel suo contesto. Questo perché non ha creato questi fagioli. Come ho detto in precedenza, quando Spring esegue la scansione delle classi, cerca le proprie annotazioni Spring. E se Spring non trova queste annotazioni, allora no t pensare che queste classi corrispondano ai bean che ha bisogno di creare. Per risolvere questo problema è sufficiente aggiungere il file@Componentannotazione davanti a ciascuna delle nostre classi di animali.

@Component
public class Cat {
	private String name = "Oscar";
	...
}
Ma c'è di più. Se dobbiamo dire esplicitamente a Spring che il bean per questa classe dovrebbe avere un nome specifico, indichiamo il nome tra parentesi dopo l'annotazione. Ad esempio, per dire a Spring di dare il nome " parrot-polly" al fagiolo pappagallo, che è il nome che useremo per ottenere questo pappagallo nel mainmetodo, dovremmo fare qualcosa del genere:

@Component("parrot-polly")
public class Parrot {
	private String name = "Polly";
	...
}
Questo è il punto centrale della configurazione automatica . Scrivi le tue classi, contrassegnale con le annotazioni necessarie e comunica a Spring il pacchetto che contiene le tue classi. Questo è il pacchetto che verrà eseguito dal framework per trovare annotazioni e creare oggetti di queste classi. A proposito, Spring non cerca solo @Componentle annotazioni, ma anche tutte le altre annotazioni che ereditano questa. Ad esempio, @Controller, @RestController, @Service, @Repositorye altro, che introdurremo nei prossimi articoli. Ora proveremo a fare la stessa cosa usando la configurazione basata su Java . Per iniziare, rimuovi il file@Componentannotazioni delle nostre classi. Per rendere le cose più impegnative, immagina di non aver scritto queste classi, quindi non possiamo modificarle facilmente, il che significa che non possiamo aggiungere annotazioni. È come se queste classi fossero impacchettate in una libreria. In questo caso, non c'è modo per noi di modificare queste classi in modo che vengano riconosciute da Spring. Ma abbiamo bisogno di oggetti di queste classi! Qui abbiamo bisogno di una configurazione basata su Java per creare gli oggetti. Per iniziare, crea un pacchetto con un nome come configs. In questo pacchetto, crea una normale classe Java, qualcosa come MyConfig, e contrassegnala con l' @Configurationannotazione.

@Configuration
public class MyConfig {
}
Ora dobbiamo modificare il main()metodo, cambiando il modo in cui creiamo il contesto. Possiamo indicare esplicitamente quale classe ha la nostra configurazione:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Se abbiamo diverse classi che creano bean e vogliamo connetterne diversi contemporaneamente, semplicemente li indichiamo tutti lì, separati da virgole:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
E se ne abbiamo troppi e li vogliamo collegare tutti contemporaneamente, allora indichiamo semplicemente il nome del pacchetto in cui sono contenuti:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.configs");
In questo caso, Spring esaminerà il pacchetto e troverà tutte le classi contrassegnate con l' @Configurationannotazione. Bene, e se abbiamo un programma davvero grande in cui le configurazioni sono suddivise in diversi pacchetti, indichiamo semplicemente un elenco delimitato da virgole di nomi dei pacchetti che contengono le configurazioni:

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");
O il nome di un pacchetto comune a tutti:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals");
Puoi farlo come vuoi, ma mi sembra che la primissima opzione, che indica semplicemente una classe con le configurazioni, si adatti meglio al nostro programma. Durante la creazione di un contesto, Spring cerca le classi contrassegnate con l' @Configurationannotazione e creerà i propri oggetti di queste classi. Tenta di chiamare metodi contrassegnati con l' @Beanannotazione, il che significa che questi metodi restituiscono bean (oggetti) che Spring aggiungerà al contesto. E ora creeremo bean per un gatto, un cane e un pappagallo nella nostra classe con una configurazione basata su Java. Questo è abbastanza semplice da fare:

@Bean
public Cat getCat() {
	return new Cat();
}
Qui creiamo manualmente il nostro gatto e lo consegniamo a Spring, che poi tiene il nostro oggetto nel suo contesto. Poiché non abbiamo dato esplicitamente un nome al nostro bean, Spring gli darà lo stesso nome del nome del metodo. Nel nostro caso, il fagiolo gatto si chiamerà " getCat". Ma poiché usiamo la classe, non il nome, per ottenere il cat bean nel mainmetodo, il nome del bean non è importante per noi. Allo stesso modo, crea un fagiolo di cane, tenendo presente che Spring darà il nome del metodo al fagiolo. Per nominare esplicitamente il nostro fagiolo pappagallo, indichiamo semplicemente il suo nome tra parentesi dopo l' @Beanannotazione:

@Bean("parrot-polly")
public Object weNeedMoreParrots() {
	return new Parrot();
}
Come puoi vedere, qui ho indicato un Objecttipo di ritorno e ho dato al metodo un nome arbitrario. Ciò non influisce sul nome del bean, perché qui abbiamo esplicitamente specificato il nome. Tuttavia, è meglio indicare un valore di ritorno più o meno significativo e un nome di metodo. Fallo se non altro per farti un favore quando riaprirai il progetto tra un anno. :) Consideriamo ora la situazione in cui abbiamo bisogno di un bean per creare un altro bean . Ad esempio, supponiamo di volere che il nome del gatto nel fagiolo di gatto sia il nome del pappagallo più la 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 per creare questo fagiolo, la struttura deve passare nel fagiolo pappagallo creato in precedenza. Di conseguenza, organizzerà la catena necessaria di chiamate di metodo: prima viene chiamato il metodo di creazione del pappagallo e poi il framework passa il nuovo pappagallo al metodo di creazione del gatto. Ecco dove entra in gioco l'iniezione di dipendenza : la primavera stessa passa il fagiolo pappagallo richiesto al nostro metodo. Se IDEA si arrabbia per la parrotvariabile, non dimenticare di cambiare il tipo di ritorno del metodo di creazione del pappagallo da Objecta Parrot. Inoltre, la configurazione basata su Java consente di eseguire assolutamente qualsiasi codice Javanei tuoi metodi di creazione dei fagioli. Puoi davvero fare qualsiasi cosa: creare altri oggetti ausiliari, chiamare qualsiasi altro metodo, anche quelli non contrassegnati da annotazioni Spring, creare loop, condizioni booleane - qualunque cosa ti venga in mente! Tutto questo non è possibile con la configurazione automatica, e ancor meno con la configurazione XML. Ora consideriamo un problema un po' più divertente. Polimorfismo e interfacce :) Creeremo un'interfaccia WeekDaye creeremo 7 classi che implementano questa interfaccia: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. Daremo all'interfaccia un String getWeekDayName()metodo, che restituirà il nome del giorno della settimana per la classe corrispondente. In altre parole, la Mondayclasse tornerà "Monday", ecc. All'avvio dell'applicazione, supponiamo che il nostro compito sia inserire nel contesto un bean corrispondente al giorno corrente della settimana. Non bean per tutte le classi che implementano l'interfaccia, ma solo il bean di cui abbiamo bisogno. WeekDayPuoi fare più o meno così:

@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 restituito è la nostra interfaccia. Il metodo restituisce un oggetto in buona fede di una delle classi che implementano l'interfaccia, a seconda del giorno corrente della settimana. Ora possiamo fare quanto segue nel main()metodo:

WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("Today is " + weekDay.getWeekDayName() + "!");
Per me, il programma mi dice che è domenica :) Sono fiducioso che se eseguo il programma domani, il contesto conterrà un oggetto completamente diverso. Nota che stiamo ottenendo il bean semplicemente usando l'interfaccia: context.getBean(WeekDay.class). Spring cercherà nel suo contesto il bean che implementa l'interfaccia e lo restituirà. Poi si scopre che la nostra WeekDayvariabile finisce con un oggetto Sunday, e mentre lavoriamo con questa variabile si applica il concetto familiare di polimorfismo. :) Ora qualche parola sull'approccio combinato , in cui alcuni bean vengono creati automaticamente da Spring, alcuni scansionando i pacchetti per le classi con l' @Componentannotazione e altri tramite la configurazione basata su Java. Considerando questo, torneremo alla versione originale, dove Cat, Dog, eParrotle classi sono state contrassegnate con l' @Componentannotazione. Supponiamo di voler creare fagioli per i nostri animali facendo in modo che Spring esegua automaticamente la scansione del entitiespacchetto, ma vogliamo anche creare un fagiolo con il giorno della settimana, come abbiamo appena fatto. Tutto quello che devi fare è aggiungere l' @ComponentScanannotazione a livello della MyConfigclasse, che indichiamo durante la creazione del contesto in main(), e indicare tra parentesi il pacchetto che deve essere scansionato e creare automaticamente i bean delle classi necessarie:

@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();
		}
	}
}
Durante la creazione del contesto, Spring vede che è necessario elaborare la MyConfigclasse. Entra nella classe e vede che ha bisogno di scansionare il en.codegym.info.fatfaggy.animals.entitiespacchetto " " e creare bean di quelle classi, dopodiché esegue il metodo MyConfigdella classe getDay()e aggiunge un WeekDaybean al contesto. Nel main()metodo ora abbiamo accesso a tutti i fagioli di cui abbiamo bisogno: sia oggetti animali che un fagiolo con il giorno della settimana. Se hai mai bisogno di fare in modo che Spring raccolga anche alcuni file di configurazione XML, puoi fare la tua ricerca sul web per trovare una spiegazione :) Riepilogo:
  • Prova a utilizzare la configurazione automatica
  • Durante la configurazione automatica, indicare il nome del pacchetto che contiene le classi di cui si desidera creare i bean
  • Queste classi sono contrassegnate con l' @Componentannotazione
  • Spring attraversa tutte queste classi, crea oggetti e li inserisce nel contesto;
  • Se la configurazione automatica non ci soddisfa per qualche motivo, utilizziamo la configurazione basata su Java
  • In questo caso, creiamo una normale classe Java i cui metodi restituiscono gli oggetti di cui abbiamo bisogno. Contrassegniamo questa classe con l' @Configurationannotazione se intendiamo scansionare l'intero pacchetto piuttosto che indicare una classe specifica con la configurazione durante la creazione del contesto
  • I metodi di questa classe che restituiscono bean sono contrassegnati con l' @Beanannotazione
  • Se vogliamo abilitare la scansione automatica quando si utilizza la configurazione basata su Java, utilizziamo l' @ComponentScanannotazione.
Se questo articolo è stato completamente confuso, prova a leggerlo tra un paio di giorni. Oppure, se sei a uno dei primi livelli di CodeGym, potrebbe essere un po' presto per studiare Spring. Puoi sempre tornare a questo articolo un po' più tardi, quando ti sentirai più sicuro delle tue capacità di programmazione Java. Se tutto è chiaro, allora puoi provare a convertire qualche tuo progetto preferito in Spring :) Se alcune cose sono chiare ma altre no, allora per favore lascia un commento :) Fammi sapere i tuoi suggerimenti e le tue critiche, se ho sbagliato da qualche parte o scritto qualche assurdità :) Nel prossimo articolo, ci tufferemo bruscamente in spring-web-mvc e creeremo una semplice applicazione web usando Spring.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION