Olá Pessoal, tudo bom?
O post de hoje é relacionado a criação de um projeto básico em Java utilizando o controlador de dependências de bibliotecas Maven e adicionando o CDI junto. Utilizaremos o post básico de criação de um projeto Maven, assim iremos continuar o projeto lá criado. Além disso descrevei um pouco sobre CDI. Veja na continuação desse post…
CDI – definição
A sigla CDI significa Context Dependency Injection for Java EE. Também conhecida como a especificação JSR 299, tem seu criador o Gavin King, mesmo criador do JBoss Seam e do Hibernate. O JBoss Seam implementa essa especificação do CDI. Apesar de o nome CDI descrever que seria somente para a versão Enterprise do Java, nós podemos utiliza-la na edição Standard também. A injeção de dependência nada mais é do que deixar a especificação assumir qual seria a forma de instanciar um objeto de uma determinada classe.
Por exemplo, em um projeto que não use CDI, provavelmente foi utilizado alguns conceitos de singleton e factory. O CDI ajuda a remover esse tipo de conceito do sistema. Não estou dizendo que utilizar os padrões seja ruim, muito pelo contrário, é que algumas tarefas se tornam bem mais simples utilizando especificações que no fim das contas irão realizar a mesma atividade. Um resumo das funcionalidades do CDI:
- Uma forma de prover e gerar objetos com estado (stateful)
- Injeção de dependências com type-safe, ou seja, trazer objetos do tipo desejado, sem serem de outros formatos.
- Injeção de dependências para diferentes ambientes (desenvolvimento, homologação, produção) sem a necessidade de configurações complexas
- Integração com Expression Languages, podendo ser utilizada com JSP e JSF.
- Notificação de eventos
- Criação de Interceptors
- Capacidade de prover uma SPI (Service Provider Interface), podendo criar novas extensões a especificação.
Então o CDI é uma especificação robusta que auxilia no desenvolvimento de projetos para ambas as versões do Java.
Uma especificação nunca é implementada ao pé da letra, apenas é criada para que outros vendors possam implementar bibliotecas seguindo esse padrão, isso ajuda na hora de trocar de uma biblioteca para outra. No nosso caso utilizaremos o JBoss Weld, que implementa esse padrão, pois o JBoss Seam deixou de ser atualizado pela JBoss.
Incluindo CDI em um Projeto Básico no Eclipse
O primeiro ponto é criar o projeto básico do Maven conforme o post relacionado.
Depois de criado, é hora de começar a adaptação nos arquivos desse projeto a fim de abrir o CDI.
Alterando o pom.xml
Abra o arquivo pom.xml, que se encontra na raiz do projeto. Adicione a dependência do Weld-se que é utilizado para que possamos executar os testes unitários ou aplicações java com CDI. O código destacado abaixo acrescenta essa dependência:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.weld.se</groupId> <artifactId>weld-se</artifactId> <version>2.4.5.Final</version> </dependency> </dependencies> |
Pronto, com esse código o maven irá adicionar a dependência do Weld ao projeto. Agora vamos alterar outros pontos para poder testar essa dependência.
Criação do arquivo beans.xml
Para que o Weld funcione corretamente, será necessário criar um arquivo no formato xml chamado beans.xml.
Para tanto devemos criar uma source folder de nome resources (não lembra como criar uma source folder? aqui) dentro da pasta src/main. Agora crie uma folder (não lembra? aqui) dentro da resources de nome META-INF (isso mesmo, tudo maiúsculo). Agora clique com o botão direito em cima da pasta META-INF por fim vá em new > File e crie o arquivo beans.xml.
Esse arquivo deverá possuir o seguinte conteúdo:
1 2 3 4 5 6 |
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> </beans> |
Agora vamos começar a trabalhar nos arquivos Java.
Criação de um package utils
Dentro de um projeto normalmente existem classes que são utilitárias a todo o sistema, para padronizar iremos criar um sub-package chamado utils, embaixo do package SeminariosCientificos. Se você não sabe como criar um package dê uma olhada aqui.
Criando a classe WeldContext
Para que possamos utilizar o CDI dentro do projeto, será necessário criar um contexto instanciando uma Singleton (não lembra? aqui) de um container weld. A classe WeldContext será criada dentro do package utils. A classe deverá criar uma instância da classe org.jboss.weld.environment.se.Weld e com ela iniciar um org.jboss.weld.environment.se.WeldContainer.
Outro aspecto interessante dessa classe é o método getBean(), que recupera uma instância de uma classe passada como parâmetro através do container weld. O código da classe está abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package br.com.mauda.SeminariosCientificos.utils; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; public class WeldContext { private static final WeldContext instance = new WeldContext(); private final Weld weld = new Weld(); private final WeldContainer container = this.weld.initialize(); private WeldContext() { // Utilizado para quando a JVM eh encerrada, encerrar o weld Runtime.getRuntime().addShutdownHook( new Thread() { @Override public void run() { try { WeldContext.this.weld.shutdown(); } catch (IllegalStateException e) { // ignore } } }); } public static WeldContext getInstance() { return instance; } @SuppressWarnings("static-access") public static <T> T getInstanciatedClass(Class<T> type) { return instance.container.current().select(type).get(); } } |
Criação de uma Entity de Teste
A fim de conseguir testar o CDI iremos criar uma classe EntityTeste dentro de um novo package dominio, sub-package de seminariosCientificos. Essa classe apenas possui a funcionalidade de armazenar uma frase. Repare que o atributo frase é iniciado com a frase “Deu certo!”. Isso é importante mencionar para que você relembre isso durante o teste. O código da classe EntityTeste está abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package br.com.mauda.SeminariosCientificos.dominio; public class EntityTeste { private String frase = "Deu certo!"; public String getFrase() { return frase; } public void setFrase(String frase) { this.frase = frase; } } |
Alteração da classe App
A classe App já criada anteriormente pelo Maven, deverá ser alterada, pois não realiza o teste necessário para o CDI. As seguintes alterações deverão ser realizadas:
- Acrescentar os imports das linhas 3 e 4;
- Remover a linha System.out.println( “Hello World!” );
- Em seu lugar acrescentar a linha new App();
- Acrescentar o código do construtor da classe App, que se encontra entre as linhas 16-27;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package br.com.mauda.SeminariosCientificos; import br.com.mauda.SeminariosCientificos.dominio.EntityTeste; import br.com.mauda.SeminariosCientificos.utils.WeldContext; /** * Teste aplicacao Java CDI * */ public class App { public static void main( String[] args ) { new App(); } public App() { //Obtem uma instancia da classe EntityTeste a partir do Contexto CDI EntityTeste entity1 = WeldContext.getInstance().getInstanciatedClass(EntityTeste.class); System.out.println(entity1.getFrase()); entity1.setFrase("Mudando frase..."); System.out.println(entity1.getFrase()); //Obtem outra instancia da classe EntityTeste a partir do Contexto CDI EntityTeste entity2 = WeldContext.getInstance().getInstanciatedClass(EntityTeste.class); System.out.println(entity2.getFrase()); } } |
É interessante observar que dentro do construtor da classe App, não instanciamos nenhum objeto, apenas chamamos o WeldContext e a partir de sua instância invocamos o método getBean, passando qual a classe que queríamos uma instância nova. Repare que modificamos a frase da entity1 para que não pareça ser o mesmo objeto quando invocamos a entity2.
Estado do Projeto
Abaixo na Figura 03, temos as pastas e arquivos que foram criados no projeto. Utilize essa imagem para verificar se seu projeto está parecido com o da figura.
Executando a classe App
Clique na classe App com o botão direito do mouse, vá em run > Java Application e o java irá executar o método main da classe App. Caso esteja tudo certo irá aparecer as seguintes mensagens do console da aplicação:
1 2 3 4 5 6 7 8 9 10 11 |
fev 17, 2017 6:31:55 PM org.jboss.weld.bootstrap.WeldStartup <clinit> INFO: WELD-000900: 2.2.10 (Final) fev 17, 2017 6:31:56 PM org.jboss.weld.bootstrap.WeldStartup startContainer INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously. fev 17, 2017 6:31:56 PM org.jboss.weld.interceptor.util.InterceptionTypeRegistry <clinit> WARN: WELD-001700: Interceptor annotation class javax.ejb.PostActivate not found, interception based on it is not enabled fev 17, 2017 6:31:56 PM org.jboss.weld.interceptor.util.InterceptionTypeRegistry <clinit> WARN: WELD-001700: Interceptor annotation class javax.ejb.PrePassivate not found, interception based on it is not enabled Deu certo! Mudando frase... Deu certo! |
Ignore as primeiras linhas, o que importa para nosso teste são as 3 ultimas. A antepenúltima indica a frase da entity1, original, após ser instanciada pelo CDI, a penúltima a alteração na frase de entity1 e a última a instanciacao da entity2 via CDI. Se vc chegou até aqui então agora vc tem configurado um projeto para utilizar CDI. A classe AppTest ficará para um próximo post.
finally{
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Rafael Nascimento says
Muito bom artigo, estava procurando exatamente isso!
Mauda says
Olá Rafael, tudo bom?
Muito obrigado pelo feedback! E espero que outros artigos possam lhe ajudar também!
Precisando estamos aqui.
Obrigado.
Adilson Barbosa says
Muito bom. Simples e direto. Parabéns!
Mauda says
Olá Adilson, tudo bom?
Obrigado pelo feedback!
Precisando estamos por aqui!
Rubens says
Excelente. Um parabéns e muito obrigado.
Mauda says
Olá Rubens, tudo bom?
Obrigado pelo feedback!
Precisando estamos aqui.