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