Aprendendo Spring: #2 – Configurando Beans

E aí pessoal, feliz ano novo a todos! Que 2017 seja uma ano abençoado por Deus!Vários tipos de feijões

Depois de muito tempo sem escrever uma linha aqui no blog, estou fazendo muita coisa em paralelo, assim não estava conseguindo me dedicar a nada, está faltando planejamento! kkkk

Durante este período (de ausência), venho estudando o Spring Framework, e estou cada dia mais empolgado.

Hoje consegui resolver/entender a configuração de beans da minha aplicação. Estou usando Spring Boot, e como já disse um post anterior, ele faz mágica!
Para mim era uma incógnita quando o Spring Boot muitas vezes injeta o objeto que eu preciso em minha classe, mais em outras ele me informava que o bean não pode ser encontrado.

 ***************************
 APPLICATION FAILED TO START
 ***************************

 Description:

  Field saldoContabil in br.com.ederleite.service.PessoaServiceImpl required a bean of type 'br.com.ederleite.service.PessoaReposity' that could not be found.

 Action:

  Consider defining a bean of type 'br.com.ederleite.service.PessoaReposity' in your configuration.
  ...

Como a própria mensagem diz, precisava configurar o bean. Mas como fazer isso?

Configuração via anotações

É possível fazer a configuração do bean via anotações. Existe uma anotação chamada @Component (org.springframework.stereotype.Component).

Toda a classe que for anotada com ela, será automaticamente gerenciada pelo Spring, e quando o bean dela for solicitado, o mesmo será injetado sem problema.

Exemplo:

 @Component
 class PessoaServiceImpl implements PessoaService {
     @Autowired
     PessoaRepository pessoaRepository;
     ...
 }

Existem algumas variações (wrappers) para @Component, elas fazem basicamente a mesma coisa, informar ao Spring que a classe é um componente, mais são bem mais claras e identificam/tipificam classe. São elas:

  • @Service
  • @Repository
  • @Controller

Reescrevendo o exemplo anterior, o mesmo fica muito mais claro:

 @Service
 class PessoaServiceImpl implements PessoaService {
     @Autowired
     PessoaRepository pessoaRepository;
     ...
 }

Configuração via XML

É possível também configurar seus beans via XML, não tenho o histórico completo, mas pelo que li por aí, é forma mais antiga de configuração de bean. Seria algo parecido com isto:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
     <bean id="pessoaService" 
           class="br.com.ederleite.service.PessoaServiceImpl">
         <constructor-arg ref="pessoaRepository"/>
     <bean>
</beans>

Mais informações em: http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/xsd-config.html

Esta forma de configuração não me agrada, não sou fã de configuração em XML, mas se existe é bom constar!

Configuração programática via Java

Um outra forma que aprendi, é a programática via Java.

É possível criar uma classe de configuração, a mesma deverá ser anotada com @Configuration (org.springframework.context.annotation.Configuration). Nela é possível criar métodos que serão responsáveis por definir/criar os beans, todos os métodos desta classe que tiver este fim, deverão ser anotados com @Bean (org.springframework.context.annotation.Bean).

Exemplo:

 @Configuration
 public class ConfigBeans {
     @Bean
     public PessoaService criarPessoaService(PessoaRepository pessoaRepository) {
         final PessoaService pessoaService = new PessoaServiceImpl(pessoaRepository);
         return pessoaService;
     }
 }

Nota: Observe que o método recebe um atributo do tipo PessoaRepository, mas quem prove este objeto? Isto é bem legal, pois o Spring se encarrega de prover este objeto ao método, quando o mesmo está anotado com @Bean.

Gosto desta alternativa, pois me dá mais flexibilidade para criação dos beans, é possível neste caso tomar a decisão de criar o objeto com a implementação de repositório X ou Y.

Configuração programática via Groovy DSL

Há um tempo atrás trabalhei em um projeto Grails, onde tive o primeiro contato com Spring, mesmo não entendo nada de Spring, foi legal ver como os beans eram configurados.

Tudo era feito através de um script Groovy, um DSL bem flexível. Gostei bastante, pois achava bem mais simples que a configuração por XML (que também é possível no Grails).

Contudo quando tive a necessidade de configurar um bean no projeto Spring Boot, não pensei duas vezes e fui atrás de saber como poderia replicar aquela experiência do Grails no Spring.

Desde a versão 4.0, o Spring Framework já tem suporte nativo ao Groovy beans DSL. A configuração é idêntica à Grails (como eles mesmo dizem, esse recurso foi emprestado do Grails).

Segue exemplo simples:

 @Configuration
 class Application implements CommandLineRunner {
    @Autowired
    SharedService service
    
    @Override
    void run(String... args) {
        println service.message
    }
 }

import my.company.SharedService
beans {
   service(SharedService) {
       message = "Hello World"
   }
}

Nota: Se a classe estiver anotada com @Configuration, é possível declarar o bean na próxima classe como no exemplo, mas caso deseje deixar um em arquivo separado, também é possível.

Para mais informações de configuração de bean usando a DSL Groovy, sugiro consultar post Groovy Bean Configuration in Spring Framework 4 ou guia do Grails, os dois são ótimas fontes de consulta.

Como fazer o Spring Boot entender minha declaração de bean?

Leal né, depois que entendi como configurar meus beans via DSL Groovy, deparei com um problema aparentemente simples, mas que demorei algumas horas até encontrar uma resposta que funcionasse. Como fazer o Spring Boot entender minha declarações de bean?

Tentei adicionar no Resources, renomear o arquivo Groovy, entre outros, até encontrar a seguinte pergunta no SteakOverflow “Spring-boot automatically import applicationContext.xml?

Na pergunta, existe um trecho de código onde o usuário usa a anotação @ImportResource({“classpath*:applicationContext.xml”}). Aí veio a ideia, vou tentar usar essa anotação passando o classpath do arquivo Groovy.

E para minha surpresa, funcionou!! \o/

Importante: Todos os tipos de configurações apresentados neste post, podem co-existir. Não há a necessidade de optar por apenas um deles.

Não sei se existe outra forma de fazer isso, ou se eu estou reinventando a roda, mais por hora, até encontrar algo melhor, vou fazendo assim.

Caso alguém saiba um jeito melhor de fazer deixe um comentário aqui no post.

Grande abraço.

4 Comentários

  1. […] Aprendendo Spring: #2: Configurando Beans […]

    Curtir

  2. […] Aprendendo Spring: #2 – Configurando Beans […]

    Curtir

  3. […] Aprendendo Spring: #2: Configurando Beans […]

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: