Visão Geral de EJB 3.0
Upcoming SlideShare
Loading in...5
×
 

Visão Geral de EJB 3.0

on

  • 6,941 views

Noções de EJB 3.0

Noções de EJB 3.0

Statistics

Views

Total Views
6,941
Views on SlideShare
6,911
Embed Views
30

Actions

Likes
9
Downloads
264
Comments
0

1 Embed 30

http://www.slideshare.net 30

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Curiosamente, java não possui POINTERs, mas references. <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Tais tarefas não são síncronas <br />
  • <br /> Na nova grafia, voo em vez do antigo vôo. <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Vamos comparar os clientes? <br />
  • <br /> Onde foi fornecido tal MeuEJB? <br />
  • <br /> O que é exatamente JNDI? <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Vamos ilustrar <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Vamos entender isto melhor, a relação entre clientes e beans. <br />
  • <br /> Isto para stateful beans. E para stateless? <br />
  • <br /> <br /> <br />
  • <br /> NullPointerException. Observe a DI (exige contêiner). <br />
  • <br /> Sim. <br />
  • <br /> Resposta a seguir. <br />
  • <br /> Vejamos o exemplo anterior <br />
  • <br /> Veja a nova versão... <br />
  • <br /> Veja a nova versão... <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Apenas a sequência (não os executaremos). Veja um refinamento dos passos. <br />
  • <br /> Slides anteriores ilustram partes desta solução. <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> Vejamos alguns detalhes <br />
  • <br /> <br /> <br />
  • <br /> Quais seriam os beans? <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> E o cliente? <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />
  • <br /> <br /> <br />

Visão Geral de EJB 3.0 Visão Geral de EJB 3.0 Presentation Transcript

  • Noções de EJB Mais alguns detalhes...
  • Três itens relevantes • Anotações (metadados) • Mínimo emprego de descritores (documentos XML) • Injeção de dependência
  • Anotações • Adiciona informação a classe, interface, método ou variável • A classe abaixo é um POJO com informação adicional para um contêiner: @Stateless public class X {...}
  • Algumas anotações • javax.annotation.Resource • javax.ejb.EJB • javax.jws.WebServiceRef • javax.persistence.PersistenceContext • javax.persistence.PersistenceUnit • javax.annotation.PostConstruct, ...
  • Descritores • O nome formal é deployment descriptors • Documentos XML (ou seja, arquivos contendo XML) • Configuram serviços oferecidos pelo contêiner (alternativa para anotações) • Tem precedência sobre anotações
  • Trecho de um descritor • <enterprise-beans> <sessions> <ejb-name>NomeDoMeuBean</ejb-name> <local>pacote.MinhaInterface</local> <ejb-class>pacote.MinhaClasse</ejb-class> ... </sessions> </enterprise-beans>
  • Injeção de dependência • Em vez do seu código requisitar, criar, localizar um objeto do qual ele depende, um contêiner injeta esta dependência no seu código • Em vez do código localizar um recurso, ele apenas diz que precisa dele. É função de “outro” código fornecer o recurso.
  • DI (segunda-parte) • Você “abre mão” de controle • Você não mais decide, alguém decide o que você irá usar • Em geral, o que será empregado é definido em um arquivo de configuração • Ao olhar o código, não se sabe exatamente quem fornecerá serviços
  • DI (terceira-parte) • Você declara dependências • Contêiner é responsável por instanciar objetos necessários e fornecê-los a quem precisa • Seu código não cria uma instância da interface X, um objeto que implementa esta interface é declarado e o contêiner se encarrega de instanciá-lo (quando preciso)
  • Exemplo • public class Main { @EJB private static ServicoRemote srv; public static void main(String... args) { System.out.println(srv.toUpper(“casa”)); } } java.lang.NullPointerException
  • Tipos de beans • Session bean @Stateless ✦ @Stateful ✦ •@MessageDriven •@Entity
  • Qual a diferença? • Session beans e message-driven beans Lógica de negócio ✦ • Entity beans Persistência ✦
  • Session beans e MDBs? • Session beans Requisições diretas de funções do cliente ✦ (calcule isto, faça aquilo, ...) • @MessageDriven Processam mensagens indiretas ✦
  • Requisições diretas!? (session beans) • Quanto custa tal carro? • Qual o saldo desta conta? • Dê-me o PDF do histórico deste aluno! • Altere o endereço de entrega deste pedido! • Acrescente esta disciplina à lista de desejadas! • Qual o próximo pedido a ser atendido?
  • Requisições indiretas!? (MDBs) • Cadastre requisição de emissão de diploma para o aluno A! Biblioteca verifica pendências ✦ Departamento verifica pendências ✦ DAA verifica pendências ✦ Software inteligente detecta legalidade ✦ • Quando todos sinalizarem “ok”, emissor de diploma imprime propriamente dito o diploma.
  • Requisições indiretas! @MessageDriven • Em geral as tarefas correspondentes não são executadas de forma síncrona Garçom (atende vários pedidos ✦ simultaneamente) instalação de ADSL, requisição de serviços... ✦ • Contraste com (@Stateless, @Stateful) Atendimento médico ✦ Reserva de voo ✦ Confirmação de inscrição, matrícula, ... ✦
  • Enfim, session beans ou MDBs? • São opções que visam mais adequadamente tratar problemas distintos • Use o que melhor atende o seu problema • Não é preciso usar ambos
  • E quanto aos tipos de Session beans? • @Stateless Funções atendidas por uma ✦ requisição • @Stateful Funções que exigem a manutenção de ✦ um diálogo com o cliente
  • Um exemplo trivial • Conversão de letras minúsculas para letras maiúsculas Definitivamente este não é um exemplo ✦ que justifica o emprego de EJB Registre isto no seu cérebro ✦
  • Exemplo (Cliente) • public class Main { @EJB private static SessionRemote srv; public static void main(String... args) { System.out.println(srv.toUpper(“casa”)); } } Resultado esperado!!!??? CASA
  • Exemplo (EJB) (interface) public class Main { @EJB SessionRemote srv; private static public static void main(String... args) { System.out.println(srv.toUpper(“casa”)); } } • @Remote public interface SessionRemote { String toUpper(String entrada); }
  • Exemplo (EJB) (stateless session bean) • @Stateless(mappedName=”MeuEJB”) public class SessionBean implements SessionRemote { public String toUpper(String entrada) { return entrada.toUpperCase(); } } public class Main { @EJB private static SessionRemote srv; public static void main(String... args) { System.out.println(srv.toUpper(“casa”)); } }
  • Visão geral do exemplo Não há dependência de Main para SessionBean (objeto de interesse será injetado pelo ACC)
  • ACC? • Application Client Container • Contêiner para o cliente? Sim! Veja o código! public class Main { @EJB SessionRemote srv; private static public static void main(String... args) { System.out.println(srv.toUpper(“casa”)); } } Quem poderia injetar um objeto que implementa SessionRemote em srv? Observe que este código não será executado pelo EJB contêiner!!!!!
  • Sou obrigado a usar um ACC? • Não! Contudo, abre-se mão da injeção de dependência!!! • Cliente que não é executado por um ACC JNDI InitialContext ctc = new InitialContext(); SessionRemote srv = (SessionRemote) ctx.lookup(“MeuEJB”); System.out.println(srv.toUpper(“casa”));
  • Comparando clientes Usa DI public class Main { @EJB Exige contêiner private static SessionRemote srv; public static void main(String... args) { (ACC) System.out.println(srv.toUpper(“casa”)); } } Exige JVM convencional InitialContext ctc = new InitialContext(); SessionRemote srv = (SessionRemote) ctx.lookup(“MeuEJB”); System.out.println(srv.toUpper(“casa”)); Não usa DI (cliente conhece um tal de “MeuEJB”)
  • @Stateless (atributo mappedName) • Anotações possuem, em geral, atributos • @Stateless possui, entre outros, o atributo mappedName • mappedName especifica o nome empregado por JNDI • Em tempo, JNDI é acrônimo de Java Naming and Directory Interface
  • JNDI • Associa nome a recurso • Permite a uma aplicação Java descobrir e recuperar um objeto de qualquer tipo • Por exemplo, obter referência para EJB InitialContext ctc = new InitialContext(); SessionRemote srv = (SessionRemote) ctx.lookup(“MeuEJB”); System.out.println(srv.toUpper(“casa”));
  • Lembra-se da discussão... • Session beans (negócio) @Stateless (ilustrado) ✦ @Stateful (próximo exemplo) ✦ • Message-driven Beans (MDBs) (negócio) Requisição indireta ✦ (processamento assíncrono)
  • @Stateful • Um diálogo (ou sessão) é mantido Seleciona o modelo ✦ Seleciona o ano ✦ Seleciona a cor ✦ Seleciona opcionais ✦ • Cliente define um estado e, em requisições posteriores, aquele estado está lá
  • @Stateful • Primeiro momento Cliente requisita um modelo específico ✦ • Segundo momento Cliente requisita um ano específico (esta ✦ requisição se aplica ao modelo selecionado anteriormente) • Ou seja, em um @Stateful bean, o estado anteriormente obtido é mantido em chamadas posteriores
  • @Stateful (mantendo estando) • Obser ve a classe abaixo (POJO) public class Carro { private String modelo; private int ano; // Métodos get/set para modelo e ano } • Transformado em stateful bean (sufixo Bean é uma convenção) @Stateful public class CarroBean {...}
  • Cliente public class Main { @EJB private static CarroRemote carro; public static void main(String... args) { exibeCarro(carro); carro.setModelo(“Fusca”); carro.setAno(1969); exibeCarro(carro); } } Ocorre NullPointerException? Não! O modelo se perde após setModelo? Não O ano se perde após setAno? Não! O bean que recebe a mensagem setModelo é o mesmo que responde ao método setAno? Sim! O mesmo bean responde todas as msgs? SIM!
  • Cliente e beans • Se existe um único cliente e um único bean, então não há como chamar outro bean! • Se existem vários clientes, então um cliente pode alterar o estado de um stateful bean consultado por outro cliente? Não! • Para cada cliente um correspondente stateful bean? Sim! • Quem mantém a correta associação entre clientes e beans? O EJB contêiner!
  • Clientes de @Stateless • Requisições são tratadas em uma única chamada, ou seja, instâncias de stateless beans podem ser compartilhadas em um pool delas! • Instâncias de stateful beans não podem ser compartilhadas!
  • Exercício • Qual o resultado da execução do comando abaixo para o código fornecido? java -cp classpath-aqui Main public class Main { @EJB private static CarroRemote carro; public static void main(String... args) { exibeCarro(carro); carro.setModelo(“Fusca”); carro.setAno(1969); exibeCarro(carro); } }
  • Exercício • Código s1.m1(); s1.m2(); • Um cliente C envia a mensagem m1 para o stateful bean S1 • Em seguida, C envia a mensagem m2 para o stateful bean S1 • Um único objeto, em execução no contêiner EJB, recebe as mensagens m1 e m2?
  • Problema • Se para cada cliente uma instância de um stateful bean é criada, então teremos um crescimento indefinido do número de instâncias no contêiner EJB?
  • Resposta • Não. Stateful beans permanecem pelo menos enquanto durar a sessão (o que não é razoável em alguns casos) • Nestes casos, use a anotação @Remove para anotar método que, quando chamado, demarca fim da sessão. • Quando cliente chama método anotado por @Remove, o cliente avisa o contêiner do fim do workflow (sessão e bean podem ser eliminados)
  • Ou seja • Para este cliente, o contêiner não poderá fazer nada até que a sessão expire, afinal, como o contêiner poderia saber que não mais requisições serão enviadas? public class Main { @EJB private static CarroRemote carro; public static void main(String... args) { exibeCarro(carro); carro.setModelo(“Fusca”); carro.setAno(1969); exibeCarro(carro); } }
  • Versão alterada • Assumindo que o método fim() está anotado com @Remove, temos abaixo um cliente bem comportado e que respeita o contêiner! public class Main { @EJB private static CarroRemote carro; public static void main(String... args) { exibeCarro(carro); carro.setModelo(“Fusca”); carro.setAno(1969); exibeCarro(carro); carro.fim(); } }
  • Como executar estes exemplos? Primeiro Passo: Instalar o contêiner
  • Glassfish (Java EE Application Server) • Obtenha o jar file correspondente https://glassfish.dev.java.net/public/downloadsindex.html • Primeiro passo java -Xmx256m -jar <glassfish-obtido>.jar • Vá para o diretório criado cd glassfish • Se não for usar recursos de clustering ant -f setup.xml
  • Iniciar/parar o glassfish • Iniciar asadmin start-domain domain1 • Testar Visite http://localhost:8080 Visite http://localhost:4848 (admin/adminadmin) • Parar asadmin stop-domain domain1
  • Tela de administração Tela de administração
  • Demais passos • Crie dois beans: um stateless e outro stateful • Criar cliente JNDI e cliente via ACC para usufruir dos dois beans • Realizar a implantação (deployment) • Executar os clientes e obser var os resultados
  • Refinamento dos passos • Criar classe anotada com @Stateful e @Remove • Criar classe anotada com @Stateless (serviço oferecido por chamada única) • Efetuar o deployment no contêiner EJB (exige instalar e iniciar) • Criar cliente contendo anotação @EBJ (ACC) • Criar cliente que faz uso de JNDI (convém usar atributo mappedName tanto em @Stateless quanto @Stateful)
  • Revisão • Session beans (camada de negócio) @Stateless ✦ @Stateful ✦ • Message-driven beans (camada de negócio) @MessageDriven ✦ Próximo foco!
  • Message-Driven Bean (MDB) Finalidade • Integração Sistema A envia mensagem para B ✦ • Processamento assíncrono Serviço é requisitado (ação posterior) ✦ • Distribuição Sistema A comunica-se com B ✦
  • Comparação • Session bean Processa requisição diretamente enviada ✦ pelo cliente • Message-Driven Bean (MDB) Processa mensagem ✦ (indiretamente recebida) Cliente não sabe quem irá tratar ✦
  • Como funciona? • Cliente envia msg • “Middleman” encarrega-se de entregar a msg ao destino • “Middleman” é confiável, ou seja, a msg será entregue, mesmo que o destino não esteja disponível no momento em que o cliente envia a msg.
  • Alguns detalhes • Troca de msgs em Java ocorre via JMS • JMS Java Message Service • MDBs dependem de JMS
  • Cenário de uso • Lembra-se da compra de automóvel? • Você seleciona o carro desejado, com a configuração desejada e requisita proposta de financiamento. • Requisição pode ser enviada a várias financiadoras (análise pode envolver atividade manual)
  • Parte do processo... • Coleta dados p/ aquisição (stateful) • Requisita proposta financiamento (pode levar dias a análise, certo?) ou seja, requisição deve ser assíncrona • MDB recebe proposta, avalia risco por perfil e, de forma assíncrona, avalia parecer de profissional (ser humano) • Profissional avalia e autoriza contato de “vendedores” (de forma assíncrona), ...
  • Graficamente... A partir deste ponto outra aplicação sinalizaria pedido de análise de proposta que, após concluída seria enviada a outro MDB para “despacho” (seria consumida por pessoal de “venda”)
  • Como é um MDB? • @MessageDriven(mappedName=”jms/Queue”) public class X implements MessageListener { public void onMessage(Message msg) { try { TextMessage txt = (TextMessage) msg; // Processa mensagem... } } }
  • Como é o “cliente”? • @Resource(mappedName=”jms/Queue”) private Destination geraProposta; @Resource(mappedName=”jms/ConnectionFactory”) private ConnectionFactory cf; // Segue código que // CRIA CONEXÃO // CRIA SESSÃO JMS API // CRIA PRODUTOR DE MENSAGENS // finalmente, ENVIA A MENSAGEM
  • JMS API!? • Sim! • Qual o package? javax.jms • Onde obter mais informações? http://java.sun.com/products/jms/ ✦
  • Não esqueça! • Para obter a fábrica de conexões @Resource(mappedName=”x”) ✦ • Para obter o destino da mensagem @Resource(mappedName=”x”) ✦ • Para tratar msgs para um dado destino @MessageDriven(mappedName=”x) ✦
  • Qual é o processo? • MDBs, quando são criados, dizem qual o destino a partir do qual receberá mensagens • Cliente envia mensagem para destino (destination) • EJB contêiner dispacha (via middleman, o message-orientedmiddleware) a mensagem para o MDB • MDB recebe msg via método onMessage onMessage?
  • MDBs implementam... • javax.jms.MessageListener (usado para receber msgs assíncronas) • Possui um único método void onMessage(Message msg)
  • Trate um MDB como • um stateless session bean, ou seja, • não assuma a manutenção de estado
  • Falta JPA! • Exemplo Isto é suficiente se atributos forem primitivos e todos devem ser persistidos! @Entity public class Aluno { @ID @GeneratedValue private long id; private String nome; ... }
  • Como usar? • Em algum lugar... • aluno.setNome(“Fulano”); entityManagerInstance.persist(aluno); Cabe ao persistence provider recuperar os atributos de aluno a serem persistidos, gerar um valor único para chave, montar uma sentença SQL compatível com o SGBD empregado e requisitar a execução.
  • O que foi visto? • Visão geral de conceitos • Visão geral de como funciona Falta uma quantidade significativa de informação que diz como usar!
  • Prática de EJB 3.0 Sequência elementar
  • Sequência Zero • Instale o Glassfish e o inicie asadmin start-domain • Verifique (http://localhost:8080) • Vá para a página do administrador http://localhost:4848 • Efetue login admin/adminadmin (conta padrão)
  • Sequência Um • Crie um stateless session bean (retorna uma frase sorteada dentre um conjunto de pelo menos 5 frases) • Crie um stateful session bean (retorna o valor de um contador que é incrementado a cada chamada) • Crie um MDB (exibe “RECEBI” para cada msg recebida)
  • Sequência dois • Crie um cliente (ACC) que exercite os três beans criados (um único cliente) • Execute o cliente e observe os resultados
  • Parabéns, se você está lendo este slide, é porque sobreviveu à iniciação em EJB. Esteja preparado para usufruir do que EJB pode oferecer!