sábado, 12 de novembro de 2016

O que são EJBs e como usá-los no Wildfly?

Java há muito tempo traz o conceito de beans, que  são classes serializaveis com atributos privados e métodos get e set para acesso a eles além de um construtor sem argumentos.

EJB, Enterprise Java Bean, é conceito do mundo JavaEE que categoriza certos tipos de classes gerenciadas pelo contâiner, terceirizando algumas tarefas "corriqueiras" e cotidianos do programador de aplicações "enterprise", tais como o ciclo de vida dos beans, transações de banco de dados, escalabilidade, segurança, etc. Assim, podemos focar no EJB em nossa lógica de negócio invés de "perder tempo" com outras particularidades.

 A vida do EJB depende do container(o wildfly, o tomee e outros), o container sabe a hora de criar e parar um EJB, podemos dar instruções para o container para executar alguns métodos, mas é o container quem manda. E é melhor assim, pois podemos fazer caquinhas - grandes poderes trazem grandes responsabilidades.

Nesse artigo vamos falar brevemente de EJBs e seus tipos, focando principalmente no tipo "Stateless", que já foram amplamente divulgados em outros posts. Vamos também nos basear na versão EJB 3.1, que é parte do JavaEE 6.

Não dá pra falar tudo, né pessoal, afinal, saiba que o livro mais famos sobre EJBs tem 560 fucking pages.

Livro sobre EJB com mais de 500 páginas.

Tipos de EJBs

 

Nossos "beans corporativos" são categorizados basicamente em session beans e message-driven beans.


  • Os message-drive beans são para trabalhar com sistema de "mensagerias", onde podemos trocar mensagens para fazer uma comunicação assíncrona entre sistemas;
  • Session beans são aqueles cujo ciclo de vida dos objetos(o período no qual o objetos são instanciados e então inutilizados) dependem de uma sessão HTTP ou não.


Os session beans são subdividos da seguinte forma:

* Stateless: Não mantém estado nenhum e são usados quando uma requisição chega ao servidor. Esses tipos de Bean podem ficar em um "pool" com outros beans, ou seja, ficam armazenados juntos e prontos para uso. Notem que esse pool é configurável. Quando uma requisição chega, o servidor pega um bean do pool e usa ele, no final da requisição, o servidor coloca ele novamente no pool para uso em futuras requisições. Por esse motivo ele não deve guardar estado, pois ele não deve estar atrelado a nenhuma requisição;
* Stateful: Os beans to tipo stateful mantém estado. Ou seja, ele pode ficar mantendo informações de diversas requisições até que ele não é mais útil. Um exemplo clássico e prático de uso é carrinho de compras, onde o bean é mantido até você completar o carrinho ou cancelar ele. Mas não vamos focar nele, não vou falar dele nesse blog uma vez que esse tipo de EJB já não é tão famoso nos tipos de sistemas que vamos falar por aqui (no geral sem estado);
* Singleton: Esse é o mais simples de entender, pois um bean singleton só é instanciado uma vez e mantido até que você pare o servidor de aplicação(ou faça o undeploy de sua app), temos sempre uma instância do mesmo. Vamos fazer um exemplo de uso dele aqui, mas lembre que um recurso desse deve ser usado com precausão, pois Singletons são famosos por quase serem um "antipattern"(na verdade são considerados assim por muitos programadores) da programação orientada a objetos.


Exemplos práticos e testes


EJB Stateless

Como falei anteriormente, nosso foco maior é nos EJBs do tipo Stateless. Nesse blog não iremos mostrar aplicações que usem conceitos de manter estado no servidor, afinal quem vos escreve é um RESTfarian que abomina as práticas stateful, pois está em levíticos.

Um class simples dentro de uma aplicação do tipo WAR no Wildfly e com a anotação @javax.ejb.Stateless já é um EJB!

Vamos começar com um exemplo onde um EJB é também um recurso REST(observe as anotações JAX-RS). Esse EJB tem um método que retorna o toString padrão do objeto e também imprime no console:



Veja o resultado abaixo de 5 requisições disparadas e notem que a cada requisição temos um novo toString retornado, isso, de certa forma, indica que novos EJBs estão sendo usados a cada requisição.

org.aprendendojee.ejb.EJBSemEstado@485f82c7
org.aprendendojee.ejb.EJBSemEstado@5b5158
org.aprendendojee.ejb.EJBSemEstado@27c9659e
org.aprendendojee.ejb.EJBSemEstado@5d682c5b
org.aprendendojee.ejb.EJBSemEstado@2f1bf3db

Notem que interessante, nessa versão do Wildfly não temos pool de EJBs  e isso foi discutido no fórum do Wildfly. Há casos (ou de acordo com a configuração) em que os EJBs podem ficar em um pool, onde eles são recuperados do pool para reuso. Não vamos focar nisso aqui, talvez um dia no blog Aprendendo JBoss!


EJB Singleton


Vamos fazer o seguinte agora: vamos transformar nosso EJB em um Singleton e vamos fazer diversas requisiões e também retornar o toString, vejam que o mesmo valor é sempre retornado. Notem que para ser um EJB singleton, nós anotamos nosso Web Service JAX-RS com javax.ejb.Singleton.




Com 5 requisições para o método vai, vejam que legal, o EJB retorna sempre o mesmo toString!

org.aprendendojee.ejb.EJBSingleton@73aa1d06 
org.aprendendojee.ejb.EJBSingleton@73aa1d06 
org.aprendendojee.ejb.EJBSingleton@73aa1d06 
org.aprendendojee.ejb.EJBSingleton@73aa1d06 
org.aprendendojee.ejb.EJBSingleton@73aa1d06 

Já o método dominhoco responde de forma diferente: quando esse método receber a requisição e durante esse tempo fizermos uma nova requisição notem que cada requisição espera o retorno da outra! Afinal, como executar em paralelo se só temos uma instância do objeto, né

19:55:08,584 INFO  [stdout] (default task-43) Eu sou org.aprendendojee.ejb.EJBSingleton@7efdc496 e dorminhoco...
19:55:09,597 INFO  [stdout] (default task-44) Eu sou org.aprendendojee.ejb.EJBSingleton@7efdc496 e dorminhoco...
19:55:10,610 INFO  [stdout] (default task-45) Eu sou org.aprendendojee.ejb.EJBSingleton@7efdc496 e dorminhoco...
19:55:11,620 INFO  [stdout] (default task-46) Eu sou org.aprendendojee.ejb.EJBSingleton@7efdc496 e dorminhoco...
19:55:12,632 INFO  [stdout] (default task-47) Eu sou org.aprendendojee.ejb.EJBSingleton@7efdc496 e dorminhoco...
19:55:13,644 INFO  [stdout] (default task-48) Eu sou org.aprendendojee.ejb.EJBSingleton@7efdc496 e dorminhoco...

Agora imaginem o Thread.sleep como uma operação da vida real, como ir ao banco de dados... Estão percebendo o problema de se usar Singleton? Esse é, na verdade, só um problema.


EJBs: Do Wildfly para o mundo

Não dá pra ignorar que um monte de coisa estranha sai no log quando subimos nossa aplicação com EJB. O que são esses textos? Por exemplo, para os dois EJBs acima temos a seguinte saída:

JNDI bindings for session bean named EJBSingleton in deployment unit deployment "brincando-com-ejbs.war" are as follows:

java:global/brincando-com-ejbs/EJBSingleton!org.aprendendojee.ejb.EJBSingleton
java:app/brincando-com-ejbs/EJBSingleton!org.aprendendojee.ejb.EJBSingleton
java:module/EJBSingleton!org.aprendendojee.ejb.EJBSingleton
java:global/brincando-com-ejbs/EJBSingleton
java:app/brincando-com-ejbs/EJBSingleton
java:module/EJBSingleton

JNDI bindings for session bean named EJBSemEstado in deployment unit deployment "brincando-com-ejbs.war" are as follows:

java:global/brincando-com-ejbs/EJBSemEstado!org.aprendendojee.ejb.EJBSemEstado
java:app/brincando-com-ejbs/EJBSemEstado!org.aprendendojee.ejb.EJBSemEstado
java:module/EJBSemEstado!org.aprendendojee.ejb.EJBSemEstado
java:global/brincando-com-ejbs/EJBSemEstado
java:app/brincando-com-ejbs/EJBSemEstado
java:module/EJBSemEstado
Bem essas saídas indicam diversos nomes JNDI para acessar o EJB fazendo lookup. Você pode fazer o lookup:

* Dentro da própria aplicação
* De outras aplicações também instaladas no Wildfly
* De uma aplicação Java standalone acessando o EJB remotamente
* E até de aplicações feitas em outras plataformas! (usando coisas como IIOP)

Há vários JNDIs pois alguns seguem o padrão Java EE de JNDI, outros são específicos do Wildfly e uns nomes podem ser para uso do EJB somente de forma remota. Ok, mas não vamos a fundo nisso hoje. É importante saber que existe!

Notem que realizar um lookup é uma maneira de usar os EJBs, mas comumente usamos CDI ou a anotação javax.ejb.EJB. 


Mais sobre EJBs


Quem já conhece sabe que omitimos muitas, muitas coisas aqui! Esse mundo é gigante. Por exemplo,já falamos que o livro mais recente da série EJB 3 in Action tem mais de 500 páginas! Vamos com certeza voltar no tema para falar de anotações específicas e outros exemplos, mas por hoje é só!

Nenhum comentário:

Postar um comentário