Annotazione @Configuration di Spring

L’annotazione @Configuration di Spring fa parte del framework core di Spring. L’annotazione di configurazione di Spring indica che la classe ha metodi di definizione di @Bean. In questo modo il contenitore di Spring può elaborare la classe e generare i bean di Spring da utilizzare nell’applicazione.

Spring @Configuration

L’annotazione di @Configuration di Spring ci consente di utilizzare le annotazioni per l’iniezione di dipendenze. Capiamo come creare classi di configurazione di Spring. Creiamo una semplice classe di bean Java.

package com.journaldev.spring;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}
	
}

Prima di utilizzare qualsiasi classe del framework Spring, dovremo aggiungere le relative dipendenze al progetto Maven.

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>

Ora creiamo la classe di configurazione di Spring.

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
}

Scriviamo una semplice classe e configuriamo la nostra semplice classe di configurazione di Spring.

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		// MyBean mb1 = ctx.getBean(MyBean.class);

		// MyBean mb2 = ctx.getBean(MyBean.class);

		ctx.close();
	}

}

Se eseguiamo l’applicazione sopra, produrrà un output simile a questo:

May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy

Notare che Spring carica i bean nel suo contesto prima ancora che li richiediamo. Questo è fatto per assicurarsi che tutti i bean siano configurati correttamente e l’applicazione fallisca rapidamente se qualcosa va storto. Inoltre, è necessario chiamare ctx.refresh(); altrimenti, si otterrà l’errore seguente quando si cercherà di ottenere un qualsiasi bean dal contesto.

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
	at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)

Se si decommentano le istruzioni in cui ottengo le istanze di MyBean, si noterà che non viene chiamato il costruttore di MyBean. Questo avviene perché lo scope predefinito dei bean di Spring è Singleton. Possiamo cambiarlo utilizzando l’annotazione @Scope.

Cosa succede se rimuoviamo @Configuration annotazione?

Cosa succede se rimuoviamo l’annotazione @Configuration dalla classe MyConfiguration. Noterai che funziona ancora come previsto e i bean di Spring vengono registrati e recuperati come classi singleton. Tuttavia, in questo caso, se chiamiamo il metodo myBean(), sarà una semplice chiamata di metodo Java e otterremo una nuova istanza di MyBean che non sarà più singleton. Per dimostrare questo punto, definiamo un altro bean che utilizzerà un’istanza di MyBean.

package com.journaldev.spring;

public class MyBeanConsumer {

	public MyBeanConsumer(MyBean myBean) {
		System.out.println("MyBeanConsumer created");
		System.out.println("myBean hashcode = "+myBean.hashCode());
	}

}

La nostra classe di configurazione Spring aggiornata è:

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

Ora quando eseguiamo la classe MySpringApp, genera l’output seguente.

MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367

Quindi MyBean non è più un singleton, ora annotiamo MyConfiguration con l’annotazione @Configuration e eseguiamo nuovamente la classe MySpringApp. Questa volta l’output sarà come segue.

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

Quindi è meglio utilizzare l’annotazione @Configuration con le classi di configurazione per assicurarci che il nostro contenitore Spring si comporti come desideriamo. Se non si vuole utilizzare l’annotazione @Configuration per qualche motivo strano, è comunque possibile creare la nostra classe di configurazione senza chiamare il metodo myBean() e utilizzare piuttosto una variabile di istanza di MyBean configurata tramite l’annotazione @Autowired. Qualcosa del genere funzionerà anche.

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Autowired
	MyBean myBean;
	
	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean);
	}
}

Questo è tutto per l’annotazione di configurazione di Spring, esamineremo altre annotazioni di Spring in futuri post.

Puoi scaricare il codice di esempio dal nostro Repository GitHub.

Source:
https://www.digitalocean.com/community/tutorials/spring-configuration-annotation