UFG - Instituto de Informática Especialização em Desenvolvimento de Aplicações Web com Interfaces Ricas EJB 3.0 Prof.: Fabrízzio A A M N Soares professor.fabrizzio@gmail.com Aula 12 Beans Orientados a Mensagens
Beans Orientados a Mensagens (MDB) Beans orientados a mensagens processam alguma lógica de negócios usando mensagens JMS enviadas para um destinatário particular, ou seja, consomem mensagens JMS através da tecnologia EJB.
Beans Orientados a Mensagens (MDB) Atualmente a partir da versão 3.0 do EJB JMS pode fazer uso de anotações assim como os outros tipos de EJBs para facilitar a sua escrita. Mesmo tendo sido incorporado a especificação de EJB nas versões passadas e não demandando a criação de interfaces home nem remota ainda era trabalhoso escrever um Message Driven Bean. Anotações, como já comentado, a partir da versão 3.0 da especificação facilitam mais este processo.
Beans Orientados a Mensagens (MDB) Os Message Driven Beans são completamente escondidos do cliente. O único meio de clientes comunicarem com os beans orientados a mensagens é enviando uma mensagem para um destinatário JMS.
Beans Orientados a Mensagens (MDB)
Beans Orientados a Mensagens (MDB) Um cliente envia uma mensagem JMS para um destino e o container passa esta mensagem JMS para uma instância do bean orientado a mensagens que tem se registrado como um receptor de mensagens para uma destinação particular.
Beans Orientados a Mensagens (MDB) Por usar um pool de instância de beans, o container é capaz de manipular as mensagens que chegam de uma forma muito mais eficiente e aumenta a escalabilidade das operações JMS. As instâncias dos beans podem ser colocadas ou retiradas do pool dependendo das necessidades do container de atender as requisições.
Beans Orientados a Mensagens (MDB) Os beans orientados a mensagens não possuem estado conversacional e portanto, são similares neste aspecto aos beans de sessão stateless. Isto não significa que estes beans não podem ter variáveis de instância, somente significa que as variáveis de instância que os beans possuírem não podem ser usadas para guardar informações de estado de um cliente particular porque não é garantido que um mesmo bean atenda um mesmo cliente.
Beans Orientados a Mensagens (MDB) Por assegurar que todas as instâncias dos beans orientados a mensagens são idênticas, o container é capaz de manipular um pequeno número de instâncias no pool e ainda manipular uma grande carga de chamadas. Isto é porque qualquer instância livre pode ser usada para manipular qualquer requisição que chegar vindo de uma destinação específica.
Beans Orientados a Mensagens (MDB) A partir da criação do bean orientado a mensagens até a sua destruição, o container gerencia estes beans exclusivamente. O container interage com os beans orientados a mensagens através de um conjunto de métodos de callback que são implementados pelo bean orientado a mensagens. Estes métodos são similares aos usados pelos beans de sessão e os beans de entidade. Estes métodos avisam ao bean que determinados eventos ocorrem ou ocorreram.
Beans Orientados a Mensagens (MDB) Um Message Driven Bean (MDB) é, portanto, um EJB que permite que as aplicações JavaEE processem mensagens de modo assíncrono. Age como um listener de mensagens Java Message Service (JMS), o qual é similar a um ouvinte de eventos, a não ser pelo fato de que, ao invés de receber eventos, ele recebe mensagens.
Beans Orientados a Mensagens (MDB) As mensagens podem ser emitidas por qualquer componente de JavaEE - um cliente da aplicação, um outro EJB, ou um componente WEB - ou por uma aplicação/sistema JMS que não usem a tecnologia JavaEE.
Diferenças entre o MDB e Beans de Sessão A diferença mais visível entre EJBs MDB e outros EJBs é que os clientes não acessam os MDBs através das interfaces. Ao contrário de um EJB session, um MDB tem somente a classe bean.
Diferenças entre o MDB e Beans de Sessão Em diversos aspectos, um MDB assemelha-se a um EJB Session Stateless 1.As instâncias de um MDB não retêm nenhum dado ou estado de conversação com um cliente específico. 2.Todas as instâncias de um MDB são equivalente, permitindo que o container EJB atribua uma mensagem a toda instância de um MDB. O recipiente pode realizar um pool destes objetos para permitir que os fluxos das mensagens sejam processados simultaneamente. 3.Um único MDB pode processar mensagens de múltiplos clientes.
Diferenças entre o MDB e Beans de Sessão As variáveis de instância do MDB podem manter o estado através da manipulação de mensagens do cliente por exemplo, uma conexão JMS, uma conexão com a base de dados, ou uma referência a um objeto EJB.
Funcionamento do MDB Quando uma mensagem chega, o container chama o método onmessage() do MDB para processar a mensagem. O método onmessage() realiza normalmente um cast da mensagem para um dos cinco tipos de mensagem JMS e manipula a mensagem de acordo com a lógica do negócio da aplicação.
Funcionamento do MDB Uma mensagem pode ser entregue a um MDB dentro de um contexto da transação, de modo que todas as operações dentro do método onmessage() sejam parte de uma única transação. Se ao processar a mensagem for executado um roolback, a mensagem irá ser novamente enviada.
Escrevendo um MDB Aplicações que utilizam JMS são chamadas de JMS Clients, e o sistema de mensagens que realiza o roteamento e entrega de mensagens é chamado de JMS Provider. Uma JMS Application é um sistema composto por muitos JMS Clients e, geralmente, um JMS Provider.
Escrevendo um MDB Um JMS Client que manda mensagens é chamado de producer, e um JMS Client que recebe uma mensagem é chamado de consumer. Um JMS Client pode ser ao mesmo tempo um producer e um consumer!
Message Driven Bean 1. package com.ejb.mdb; 2. import javax.ejb.messagedriven; 3. import javax.jms.message; 4. import javax.jms.messagelistener; 5. @MessageDriven 6. public class ExemploMDB implements MessageListener { 1.public void onmessage(message message) { 2... 3.} 7. }
Escrevendo um MDB Observe acima que um MDB é definido através do uso de anotações. É utilizada a anotação @javax.ejb.messagedriven para anotar a classe com um MDB. Todo MDB implementa a interface javax.jms.messagelistener que obrigará o desenvolvedor a implementar o método onmessage() para tratar o recebimento de mensagens de um client producer. O código a ser executado quando o MDB receber uma mensagem é posto no método onmessage().
Escrevendo um MDB Um EJB pode ser um consumidor de mensagens assíncronas como o mostrado no exemplo acima ou pode ser um produtor de mensagens para que clientes JMS as recebam. Todo MDB deve estar escutando uma fila de mensagens (Queue) ou estar inscrito para receber mensagens de um tópico (Topic).
Tópicos Aqui uma mensagem JMS será enviada para um Topic do container EJB e este irá imediatamente realizar um envio de uma cópia desta mensagem para todos aqueles clientes que estiverem inscritos para receber mensagens daquele tópico. Os MDBs que estiverem inscritos para receber mensagens do tópico irão receber.
Escrevendo um MDB
Fila Este modelo JMS baseado em fila (queue) permitirá um cliente enviar mensagens para a fila de forma que outros possam consumir as mensagens da fila. Uma diferença importante com relação ao modelo topic é que a mensagem de uma fila será consumida apenas por um cliente e não distribuída para todos os inscritos como acontece com um topic.
Fila
Fila Observe que somente um MDB irá consumir a mensagem. Todas as mensagens enviadas por clientes ficam na Fila aguardando alguém que as consuma.
Escolha do Modelo A decisão de qual modelo utilizar na sua aplicação irá depender em cada caso do que precisa ser representado com JMS. O modelo de Queue garante que somente um cliente irá processar a mensagem recebida. É muitas vezes conhecido portanto com pier-topier (P2P).
EJB como Produtor JMS Um EJB Session também pode ser um produtor de mensagens para um topic. Neste caso o EJB ao executar deve criar uma sessão com o topic e enviar a ele uma mensagem.
Ciclo de vida de um MDB Os beans orientados a mensagens são normalmente criados quando o container inicializa. O descritor de configuração pode dar ao publicador ou o assembler do bean a habilidade para especificar quantos beans orientados a mensagens estarão disponíveis na inicialização e também qual é o máximo de beans que podem ser criados. É função do container garantir que as instâncias do bean no pool estarão disponíveis antes das mensagens JMS chegarem.
Ciclo de vida de um MDB O container primeiro chama um construtor com nenhum argumento para o bean, construtor default, logo em seguinda serão injetadas as anotações. Após isto o container chama o método anotado com @javax.annotation.postconstruct na instância do bean recém criado. Neste ponto pode-se colocar códigos de inicialização se seu bean necessita de determinados recursos para completar a lógica de negócios.
Ciclo de vida de um MDB O EJB container frequentemente cria um pool de instâncias de message-driven beans. Para cada instância, o EJB container instancia o bean e faz as seguintes tarefas: 1.Chama o método construtor 2.Injeta as anotações se houverem 3.Chama o método anotado com @javax.annotation.postconstruct 4.Chama o método onmessage()
Ciclo de vida de um MDB
Ciclo de vida de um MDB Como um stateless session bean, um message-driven bean não é nunca colocado no estado de passivo, e possui somente os estados mostrado a acima: não existente e pronto para receber mensagens. No final do ciclo de vida, o container chama o método anotado com @javax.annotation.predestroy. A instância do bean está então pronta para ser coletada pelo garbage collector.
Quando usar um MDB Os Session Beans e os Entity Beans permitem que você emita mensagens JMS e as receba de modo síncrono, mas não assíncrono. Para evitar desperdiçar recursos de servidor, você pode preferir não usar um bloqueio de execução síncrono em um componente no servidor. Para receber mensagens assíncronas, use um Message-Driven Bean.