A anotação @Configuration do Spring faz parte do framework central 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 Spring @Configuration
O Spring @Configuration permite que usemos anotações para injeção de dependência. Vamos entender como criar classes de Configuração do Spring. Vamos criar uma classe de bean 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 simples classe de configuração do 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 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 termos solicitado. 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 você descomentar as declarações onde estou obtendo instâncias de MyBean, perceberá que o construtor de MyBean não está sendo chamado. 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. Você perceberá que ainda funciona conforme esperado, e os beans do Spring são registrados e recuperados como classes singleton. No entanto, nesse caso, se fizermos uma chamada ao método myBean()
, será uma chamada de método Java comum, e obteremos uma nova instância de MyBean, que não permanecerá singleton. Para comprovar esse 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 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
, ela gera a seguinte saída.
MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367
Portanto, MyBean não é mais um singleton, agora vamos anotar MyConfiguration
novamente com a anotação @Configuration
e executar a classe MySpringApp
novamente. 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 desejada. Se você não quiser usar a anotação @Configuration por alguma razão estranha, 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 explorar 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