Anotação @Configuration do Spring

A anotação @Configuration do Spring faz parte do framework principal do Spring. A anotação de Configuração do Spring indica que a classe possui métodos de definição de @Bean. Assim, o contêiner do Spring pode processar a classe e gerar Spring Beans para serem usados na aplicação.

O @Configuration

O @Configuration do Spring nos permite usar anotações para injeção de dependência. Vamos entender como criar classes de Configuração do Spring. Vamos criar uma classe java simples.

package com.journaldev.spring;

public class MyBean {

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

Antes de usarmos qualquer uma das classes do framework Spring, teremos que adicionar suas dependências ao projeto Maven.

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

Agora vamos criar a classe de Configuração do 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();
	}
	
}

Vamos escrever uma classe simples e configurar nossa classe de configuração Spring simples.

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 você executar a aplicação acima, ela produzirá uma saída 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

Observe que o Spring carrega os beans em seu contexto antes mesmo de solicitarmos. Isso é feito para garantir que todos os beans estejam devidamente configurados e que a aplicação falhe rapidamente se algo der errado. Além disso, ctx.refresh() deve ser chamado, caso contrário, receberemos o seguinte erro ao tentar obter qualquer bean do 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)

Se descomentarmos as instruções onde estou obtendo instâncias de MyBean, perceberemos que não está chamando o construtor de MyBean. Isso ocorre porque o escopo padrão dos beans do Spring é Singleton. Podemos alterá-lo usando a anotação @Scope.

E se removermos a anotação @Configuration?

O que acontecerá se removermos a anotação @Configuration da classe MyConfiguration. Perceberemos que ainda funciona conforme esperado, e os beans do Spring são registrados e recuperados como classes singleton. No entanto, nesse caso, se chamarmos o método myBean(), será uma chamada de método Java comum, e obteremos uma nova instância de MyBean, que não permanecerá como singleton. Para comprovar este ponto, vamos definir outro bean que utilizará uma instância 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());
	}

}

Nossa classe de Configuração do Spring atualizada é:

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

Agora, quando executamos a classe MySpringApp, gera a seguinte saída.

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

Então MyBean não é mais singleton, agora vamos anotar MyConfiguration com a anotação @Configuration novamente e executar a classe MySpringApp. Desta vez, a saída será como abaixo.

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

Portanto, é melhor usar a anotação @Configuration com classes de configuração para garantir que nosso contêiner Spring esteja se comportando da maneira que queremos. Se você não quiser usar a anotação @Configuration por alguns motivos estranhos, ainda podemos criar nossa classe de configuração não chamando o método myBean() e em vez disso usando uma variável de instância de MyBean configurada através da anotação @Autowired. Algo como o código abaixo também 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);
	}
}

Isso é tudo para a anotação de configuração do Spring, vamos analisar outras anotações do Spring em futuras postagens.

Você pode baixar o código de exemplo do nosso Repositório no GitHub.

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