Anotación @Configuration de Spring

La anotación @Configuration de Spring es parte del marco principal de Spring. La anotación de configuración de Spring indica que la clase tiene métodos de definición de @Bean. Por lo tanto, el contenedor de Spring puede procesar la clase y generar Spring Beans para ser utilizados en la aplicación.

Spring @Configuration

La anotación @Configuration de Spring nos permite utilizar anotaciones para la inyección de dependencias. Veamos cómo crear clases de configuración de Spring. Creemos una clase de bean Java simple.

package com.journaldev.spring;

public class MyBean {

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

Antes de usar cualquiera de las clases del framework de Spring, tendremos que agregar sus dependencias al proyecto Maven.

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

Ahora creemos la clase de configuración de 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();
	}
	
}

Escribamos una clase simple y configuremos nuestra clase de configuración de Spring simple.

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();
	}

}

Si ejecutas la aplicación anterior, producirá una salida como esta:

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

Ten en cuenta que Spring carga los beans en su contexto antes de que los solicitemos. Esto se hace para asegurarse de que todos los beans estén correctamente configurados y que la aplicación falle rápidamente si algo sale mal. Además, se debe llamar a ctx.refresh(), de lo contrario, obtendremos el siguiente error cuando intentemos obtener algún bean del contexto.

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)

Si descomentas las declaraciones donde estoy obteniendo instancias de MyBean, notarás que no se está llamando al constructor de MyBean. Esto se debe a que el ámbito predeterminado de los beans de spring es Singleton. Podemos cambiarlo usando la anotación @Scope.

¿Qué pasa si eliminamos la anotación @Configuration?

¿Qué sucederá si eliminamos la anotación @Configuration de la clase MyConfiguration? Notarás que aún funciona como se esperaba y los beans de Spring se registran y recuperan como clases singleton. Pero en este caso, si hacemos una llamada al método myBean(), será una llamada de método java simple y obtendremos una nueva instancia de MyBean y no permanecerá como singleton. Para demostrar este punto, definamos otro bean que utilizará la instancia de MyBean.

package com.journaldev.spring;

public class MyBeanConsumer {

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

}

Nuestra clase de Configuración de Spring actualizada es:

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());
	}
}

Ahora, cuando ejecutamos la clase MySpringApp, genera la siguiente salida.

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

Así que MyBean ya no es un singleton, ahora anotemos MyConfiguration con la anotación @Configuration nuevamente y ejecutemos la clase MySpringApp. Esta vez, la salida será como sigue.

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

Por lo tanto, es mejor usar la anotación @Configuration con clases de configuración para asegurarnos de que nuestro contenedor Spring se comporte de la manera que deseamos. Si no deseas utilizar la anotación @Configuration por alguna razón extraña, aún podemos crear nuestra clase de configuración sin llamar al método myBean() y en su lugar usando una variable de instancia de MyBean configurada mediante la anotación @Autowired. Algo como el siguiente código también funcionará.

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);
	}
}

Eso es todo para la anotación de configuración de Spring, investigaremos otras anotaciones de Spring en futuras publicaciones.

Puedes descargar el código de ejemplo desde nuestro Repositorio de GitHub.

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