Java CDI — Um tutorial

Victor Osório
3 min readFeb 26, 2019

--

Fiz um tutorial mais recente no dev.to/vepo.

Java CDI é um padrão de software, incorporado desde o Java EE 6, para lidar com Injeção de Contexto e Dependência. A especificação é uma das implementações da técnica Inversão de Controle (Inversion of Control).

Sumário

  1. Configurando, Injetando dependências e Interceptando métodos
  2. Usando Qualifiers e chamando programaticamente
Jakarta EE é o novo nome do Java EE.

Configurando o projeto

Para que as dependências sejam encontradas pelo Container CDI, é preciso que exista o arquivo beans.xml na pasta META-INF.

Em um projeto maven, esse arquivo ficaria em src/main/resources/META-INF/beans.xml.

Injetando Dependências

Para injetar uma dependência em qualquer lugar do código, basta se usar a anotação @Inject.

No código acima, o campo myManager será inicializado automaticamente desde que a classe tenha um construtor publico sem parâmetros.

Provendo Dependências

Para que as dependências possam ser injetadas, é preciso que algum trecho de código seja chamado. No código abaixo definimos a classe MyManager.java.

A inicialização e a finalização desse objeto será responsabilidade do Container. Observer que a anotação @ApplicationScoped define o comportamento desses objetos, nesse caso só existirá uma instância que é iniciada juntamente com o container. Para ver os outros escopos existentes:

  1. ApplicationScoped
  2. ConversationScoped
  3. Dependent
  4. NormalScope
  5. RequestScoped
  6. SessionScoped

Provendo Dependências — Factories

Caso a dependência seja uma inplementação externa, é possível criar uma Factory para a dependência.

Usando uma Factory, é necessário muito cuidado para ver se não há Memory Leak, pois o Container CDI irá chamar o metodo com @Produces várias vezes.

Enviando e Recebendo events

Para criar uma aplicação com alta coesão e baixo acoplamento, muitas vezes não é necessário que uma funcionalidade chame a outra. Quando uma compra é finalizada, a nota fiscal pode ser emitida sem que o código de finalização chame o código de emissão. Isso pode ser feito usando eventos.

Usando o Java CDI, para se emitir um evento, basta injetar uma instância da class javax.enterprise.event.Evente disparar o evento.

Na outra ponta, rodando dentro da mesma JVM, deve estar o código que processa esse evento usando a anotação @Observe:

Interceptando Métodos

Uma outra possibilidade com CDI é criar interceptors, isso pode ser muito útil para se construir aplicações usando Programação Orientada a Aspecto. A mágica nesse caso não aparece tão fácil.

Primeiro crie uma Annotation descrevendo o que deseja ser feito:

O próximo passo é implementar o que deve ser feito durante a execução, para isso crie o Interceptor:

No caso acima, estou apenas logando a execução, mas poderia ser um controle transacional, ou uma auditoria.

Para que o container CDI saiba da existência desse Interceptor, é necessário adicionar ele ao beans.xml.

Pronto! Agora funcionará!

Criando o Container

O container CDI já é inicializado em muitos projetos Jakarta EE, antigo Java EE. Como exemplo veja o código gerado pelo Thorntail.io.

Criando o Container em aplicações Java SE

Não é preciso que seja um container Web com Jakarta EE para rodar aplicações CDI. Dá para se configurar o container para pequenos projetos, que são bastante úteis como microserviços de backend, por exemplo, processar eventos Kafka.

Para isso adicione como dependência o Weld, e inicialize o container manualmente.

Conclusão

Java CDI é um padrão que pode lhe ajudar a criar aplicações mais organizadas reduzindo o acoplamento. Também é possível criar soluções aparentemente mágicas, mas que na verdade são gerenciadas por um código robusto e bem testado!

Continuação

Código fonte

O exemplo desse tutorial pode ser encontrado no meu github:

--

--

Victor Osório
Victor Osório

Written by Victor Osório

Senior Software Engineer@Openet | Java | Software Architect | Technology | Society

Responses (3)