[ JAVA EE ] CDI pt. 1— O que é e como funciona
Olá de novo, hoje vamos ver como a Injeção de Dependências e Contextos (CDI) especificada na JSR 299 muda a forma como desenvolvemos nossas aplicações.
Antes de falar sobre o CDI em si, é interessante deixarmos claro o que seria essa Injeção de Dependência (DI - Dependency Injection). E para entendê-la, precisamos saber o que é Inversão de Controle (IoC - Inversion of Control):
Inversão de controle é um padrão de desenvolvimento onde o controle de execução do código é invertido em relação ao método tradicional, ela não é mais definida diretamente pelo programador e sim por uma infraestrutura de software, como um container. Ela ocorre sempre que delegamos o controle das dependências entre módulos ou do ciclo de vida de uma execução para essa infraestrutura
Com a IoC nosso código não se preocupa em como encontrar as dependências que necessitam, ele só pede o que precisa ao nosso container e este por sua vez injeta essa dependência onde for necessário, daí o nome Injeção de Dependência. Tá, legal, mas aí você pode perguntar:
Pra que eu vou querer gastar tempo com isso? Eu mesmo posso ir lá e buscar as dependências que preciso como sempre fiz
É um questionamento válido, muita gente não vê sentido nisso de primeira (principalmente os iniciantes), porém, encontrei uma boa analogia no Stack Overflow que ajuda a entender melhor a utilidade disso tudo:
Imagine que você seja uma criança de 5 anos, e quer pegar algum lanche na geladeira por conta própria, alguns problemas podem acontecer. Você pode esquecer a porta aberta, você pode acabar pegando algo que o papai e a mamãe não querem que você tenha, você pode até estar procurando por algo que nem sequer existe ou que esteja com o prazo de validade vencido.
O que você deveria fazer é declarar uma necessidade, “Eu preciso de algo para comer e beber” e então com certeza seu cuidador providenciará tudo que necessita quando você sentar-se para comer.
E como isso funcionaria na prática? Digamos que temos uma interface PersonService
somente com um método addPerson
que adiciona novos usuários ao sistema e uma classe DefaultPersonService
que implementa essa interface:
E temos também um controlador responsável por receber nosso usuário e em seguida delegar a função de adicionar o usuário para uma implementação de PersonService
:
Nos códigos acima podemos notar algumas coisas, o nosso PersonController
está realizando uma chamada a um método da interface PersonService
mas em momento algum instanciamos uma implementação dessa interface, então como esse código funcionaria? Através da Injeção de Dependência !
A anotação @Inject
age como nossa criança de 5 anos, ele declara para nosso cuidador (container) que necessitará de uma implementação de PersonService
em algum momento, assim sendo, quando a hora chegar o container já terá providenciado e injetado a dependência necessária, garantindo a execução de nosso código.
Nesse exemplo como só temos uma implementação de PersonService
, o container injetará uma instancia de DefaultPersonService
, quando falarmos sobre qualificadores veremos as melhores maneiras de como tratar pontos de injeção ambíguos.
Como utilizar
Antes de mais nada, precisamos habilitar o CDI em nosso projeto, podemos fazer isso facilmente apenas criando um arquivo xml chamado beans.xml no diretório src/main/webapp/WEB-INF/
de nosso projeto Maven Web
.
Lembrando que o CDI é uma especificação, existem diversas implementações dessa especificação sendo a mais conhecida a implementação JBoss Weld
então verifique se seu servidor de aplicação (ou container web) já possui sua implementação do CDI, caso contrário, você mesmo pode adicioná-la no pom.xml:
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.4.6.Final</version>
</dependency>
Espero que tenham gostado dessa primeira parte da série sobre CDI, em breve falaremos sobre escopos, qualificadores, etc. Portanto fiquem ligados! Dúvidas, correções e sugestões são bem vindas, até mais!