Upload
lydat
View
213
Download
0
Embed Size (px)
Citation preview
Enterprise Java Beans (III)
Professor: Diego Passos
UFF
Baseado no material original cedido pelo Professor
Carlos Bazilio
Última Aula
• Disponibilização do EJB no container.
– Arquivo descritor.
– Opções de Segurança.
– Empacotamento do EJB.
• Utilização do Bean no lado cliente.
– Clientes locais vs. Clientes Remotos.
– Localização de interfaces home.
– Criação de beans.
– Invocação de métodos.
Nesta Aula
• Anotações.
– E como são usadas para implementar EJBs.
• Especificidades das beans de sessão.
– Beans stateless.
– Beans statefull.
– Gerenciamento (pelo container).
– Suporte transacional.
Anotações
• Atualmente, Java inclui uma funcionalidade chamada de Annotations.
• São pequenas “notas” deixadas pelo programador ao longo do código.
– Metadados do código-fonte.
• São usadas para vários objetivos:
– Como informações ao compilador.
• Supressão de warnings, detecção de erros, ...
– Para geração de artefatos de disponibilização.
• Geração de XMLs.
– Processamento em tempo de execução.
Anotações: Sintaxe Básica
• Anotações são iniciadas pelo caracter ‘@’.
• Por convenção, anotações geralmente aparecem em uma linha sozinhas.
– Há exceções.
• Anotações contém um nome.
@Override
void mySuperMethod(){...}
Anotações: Sintaxe Básica (II)
• Anotações podem incluir elementos.
– Listados entre parêntesis.
• Elementos podem ou não ter nomes.
• Elementos sempre têm valores.
@Author(
name = “Benjamin Franklin",
date = "3/27/2003" )
class MyClass() { ... }
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }
@SuppressWarnings("unchecked")
void myMethod() { ... }
Anotações: Sintaxe Básica (III)
• Anotações podem incluir elementos.
– Listados entre parêntesis.
• Elementos podem ou não ter nomes.
• Elementos sempre têm valores.
@Author(
name = “Benjamin Franklin",
date = "3/27/2003" )
class MyClass() { ... }
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }
@SuppressWarnings("unchecked")
void myMethod() { ... }
Anotações: Sintaxe Básica (IV)
• Anotações estão associadas a partes do código “próximas”.
– Exemplo: a declaração que segue a anotação.
• A um mesmo trecho de código, podemos associar múltiplas anotações.
@Author(name = "Jane Doe")
@EBook
class MyClass { ... }
Anotações: Definindo um tipo de Anotação
• Em muitos casos, desenvolvedores só precisam utilizar tipos pré-definidos de anotação.
• Às vezes, no entanto, é interessante definir novos tipos.
• Exemplo: documentação de classes.
public class Generation3List extends Generation2List {
// Author: John Doe
// Date: 3/17/2002
// Current revision: 6
// Last modified: 4/12/2004
// By: Jane Doe
// Reviewers: Alice, Bill, Cindy
// class code goes here
}
Anotações: Definindo um tipo de Anotação (II)
• Pode-se definir uma anotação para substituir os comentários.
@interface ClassPreamble {
String author();
String date();
int currentRevision() default 1;
String lastModified() default "N/A";
String lastModifiedBy() default "N/A";
// Note use of array
String[] reviewers();
}
Anotações: Definindo um tipo de Anotação (III)
• Código anotado:
@ClassPreamble (
author = "John Doe",
date = "3/17/2002",
currentRevision = 6,
lastModified = "4/12/2004",
lastModifiedBy = "Jane Doe",
// Note array notation
reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {
// class code goes here
}
Anotações: Tipos Padronizados
• Existem vários tipos de anotação padronizados pela linguagem.
• Anotação @Deprecated
– Indica que um elemento está obsoleto e não deve mais ser usado.
• Elementos: classes, métodos, atributos.
– Uso de elemento anotado com @Deprecated causa warning de compilação.
@Deprecated
static void deprecatedMethod() { ... }
Anotações: Tipos Padronizados (II)
• Anotação @Override
– Indica que elemento (método, tipicamente) deve sobrecarregar um correspondente na superclasse.
– Não é necessário, mas evita erros.
• Se método anotado não sobrecarrega outro, compilador gera um erro.
// Se não houver um método com mesma assinatura na superclasse,
// compilador acusa erro.
@Override
int overriddenMethod() {...}
Anotações: Tipos Padronizados (III)
• Anotação @SupressWarnings
– Diz ao compilador para suprimir mensagens de warning que resultariam da compilação.
– Útil quando estamos cientes do warning e julgamos que ele não é relevante para aquela situação.
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
// Tentamos usar um método marcado como deprecated.
// Sabemos disso e assumimos a responsabilidade.
objectOne.deprecatedMethod();
}
Anotações: Tipos Padronizados (IV)
• Anotação @SupressWarnings
– Há dois tipos de warnings em Java: “deprecation” e “unchecked”.
– É possível desativar múltiplos warnings de uma só vez.
@SuppressWarnings({"deprecation“, “unchecked”})
void useDeprecatedMethod() {
// Tentamos usar um método marcado como deprecated.
// Sabemos disso e assumimos a responsabilidade.
objectOne.deprecatedMethod();
}
Anotações: Processamento
• Quando um código em Java é compilado, as anotações são processadas pro plug-ins do compilador.
– Chamados também de “processadores de anotações”.
• Estes processadores podem gerar:
– Mensagens durante a compilação.
– Outros arquivos Java.
– Outros recursos (como arquivos XML).
• Os artefatos gerados pelos processadores podem também ser compilados e processados.
– Podem também alterar o código anotado.
• Note que as anotações podem ser incluídas nas classes compiladas.
– Ficam disponíveis em tempo de execução.
Anotações: Usos Típicos
• Anotações são utilizadas pelo compilador, como já visto.
• Mas é também comum o uso das mesmas em Frameworks.
– Podem gerar configurações a partir de anotações do código.
– Evitam a necessidade de referenciar classes, métodos em arquivos externos.
• Exemplos de frameworks (já vistos no curso) que permitem o uso de anotações:
– Servlets: anotação @WebServlet(value=“/url”)
• Define mapeamento de URL para o servlet anotado.
– JSF (beans gerenciadas): anotações @ManagedBean(name=“nome”), @RequestScope, @SessionScope, e @ApplicationScope
• Definem que classe anotada é uma bean gerenciada com um escopo específico.
EJB 3
• EJB 3 difere das versões anteriores pelos seguintes fatores:
– Uso de POJO’s (Plain Old Java Objects);
• Classes simples em Java;
• O modelo inicial de componentes (interfaces Home e descritores XML, por exemplo) foi substituído por objetos e serviços EJB oferecidos pelo contêiner;
– Anotações em Java;
• Permitem a definição de atributos de código e opções de configuração diretamente no código Java;
– Injeção de Dependência.
• Referência: http://java.sun.com/products/ejb
EJB 3: Exemplos da Primeira Aula
• Nas duas primeiras aulas, vimos a maneira original de criar/manipular EJBs.
• Implementação de uma EJB precisa dos seguintes passos:
– Definição das interfaces cliente (local e remota).
– Definição das interfaces home (local e remota).
– Implementação do bean.
– Criação do deployment descriptor.
– Criação de arquivos de configuração específicos do container.
– Criação das classes geradas pelo container.
– Empacotamento da EJB em um arquivo .jar.
• Como é este processo na especificação EJB 3.0?
– Definição das interfaces cliente (local e remota).
– Implementação do bean.
– Compilação e empacotamento.
EJB 3: Criação da Interface Cliente (Remota)
import com.oreilly.jent.ejb.NoSuchPersonException;
@Remote
public interface ProfileManager {
public Profile getProfile(String acctName)
throws NoSuchPersonException;
}
• Não precisa estender a interface EJBObject.
• Utiliza a anotação @Remote.
• Opcional se houver apenas a interface remota.
• É uma POJO.
EJB 3: Criação da Interface Cliente (Local)
import com.oreilly.jent.ejb.NoSuchPersonException;
@Local
public interface ProfileManagerLocal extends
ProfileManager {
}
• Não precisa estender a interface EJBLocalObject.
• Utiliza a anotação @Local.
• Opcional se houver apenas a interface local.
• É uma POJO.
• Pode estender a interface remota, por exemplo.
EJB 3: Implementação da Bean
import javax.ejb.*;
@Stateless
@Remote(ProfileManager.class)
@Local(ProfileManagerLocal.class)
public class ProfileManagerBean implements
ProfileManagerLocal {
...
}
• Utiliza várias anotações:
• @Stateless: indica EJB de Sessão Stateless.
• @Remote: indica que a EJB terá interface cliente remota.
• @Local: indica que a EJB terá interface cliente local.
EJB 3: Implementação da Bean (II)
import javax.ejb.*;
@Stateless
@Remote(ProfileManager.class)
@Local(ProfileManagerLocal.class)
public class ProfileManagerBean implements
ProfileManagerLocal {
...
}
• Não é necessário implementar a interface SessionBean.
• Consequências:
• Não é necessário implementar os métodos ejbCreate(), ejbPassivate(), ..., a menos que precisemos deles.
EJB 3: Implementação da Bean (III)
import javax.ejb.*;
@Stateless
@Remote(ProfileManager.class)
@Local(ProfileManagerLocal.class)
public class ProfileManagerBean implements
ProfileManagerLocal {
...
}
• Se precisarmos dos métodos de gerência do ciclo de vida, podemos dar quaisquer nomes a eles.
• No entanto, devemos identificá-los com anotações:
• @PostConstruct
• @PreDestroy
• @PostActivate
• @PrePassivate
EJB – Tipos de Beans
• Como visto na primeira aula, há três tipos de EJBs.
– EJBs de sessão.
– EJBs de entidade.
– EJBs orientadas à mensagens.
• A diferença entre os tipos de EJB está no tipo de funcionalidade que cada uma oferece.
• Especificamente, as EJBs de sessão se prestam a fornecer um conjunto bem definido de funcionalidades a clientes.
– Clientes obtém uma referência a uma EJB de sessão.
– Pedem um ou mais serviços.
EJB – Beans de Sessão
• Beans de sessão recebem este nome pelo seu ciclo de vida típico.
– Elas não são persistentes.
– Seu ciclo de vida em geral é definido por sessões de uso.
• Beans de sessão podem ser subdivididas em mais duas classificações:
– Stateless Session Beans: beans de sessão que não guardam estado.
– Stateful Session Beans: beans de sessão que guardam estado.
EJB – Beans de Sessão Stateless
• Estas beans não guardam estado relacionado ao cliente entre chamadas dos seus métodos.
• O resultado de um método não depende das chamadas anteriores feitas pelo cliente.
• Como estas beans não guardam estado, suas instâncias são intercambiáveis.
– Qualquer instância pode ser usada a qualquer momento para tratar pedidos de qualquer cliente.
– Container pode guardar um pool de instâncias.
• Ao ser requisitada por um cliente, container retorna qualquer instância do pool.
• Note que declarar uma bean como stateless não garante esta característica.
– É tarefa do desenvolvedor garantir isso.
– Container simplesmente assume como verdade.
EJB – Beans de Sessão Stateful
• Estas beans armazenam estado da interação com o cliente.
• Execução de métodos pode alterar o estado interno da bean.
• Instâncias das beans pertencem a seus clientes específicos.
– Não podem ser usadas por outros clientes.
– Cliente dono de uma instância só a perde quando ativamente libera o recurso, ou quando a referência expira.
EJB – Stateful vs. Stateless
• Vamos ilustrar a diferença entre as versões stateful e stateless com um exemplo.
• O exemplo utilizado na aula anterior, do ProfileManagerBean, era um exemplo de bean stateless.
– Ele recebia requisições para encontrar um perfil.
– Ele retornava o resultado na forma de objetos do tipo Profile.
– A partir daí, interação do cliente é com o objeto Profile.
• Suponha, no entanto, que desejamos transformar o próprio perfil em uma bean de sessão.
– Cliente requisita o carregamento do perfil.
– Bean carrega o estado.
– Métodos da bean permitem manipulação do perfil.
– Exemplo de uma bean de sessão stateful.
EJB – Bean de Sessão Stateful – Outro Exemplo
• Exemplo do tutorial da sun: http://docs.oracle.com/javaee/5/tutorial/doc/bnbod.html
• Suponha um sistema web de vendas de livro que utiliza o conceito de carrinho de compras.
• Queremos implementar o carrinho de compras como uma EJB de Sessão.
• O carrinho deve ser capaz de manipular o conjunto de livros pretendidos pelo cliente.
– Adicionar livros.
– Remover livros.
– Listar o conteúdo do carrinho.
• Note que este é um exemplo claro de um bean stateful.
– Após a chamada de um dos métodos de negócio, estado da bean é alterada.
– Uma instância da bean deve ser associada a seu cliente, e apenas a ele.
EJB – Bean de Sessão Stateful – Outro Exemplo (Interface)
package com.sun.tutorial.javaee.ejb;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface Cart {
public void initialize(String person) throws BookException;
public void initialize(String person, String id) throws
BookException;
public void addBook(String title);
public void removeBook(String title) throws BookException;
public List<String> getContents();
public void remove();
}
• Neste exemplo, declaramos uma interface remota.
• Listamos os métodos de negócio.
EJB – Bean de Sessão Stateful – Outro Exemplo (Bean)
package com.sun.tutorial.javaee.ejb;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remove;
import javax.ejb.Stateful;
@Stateful
public class CartBean implements Cart {
String customerName;
String customerId;
List<String> contents;
...
• A implementação define que a bean é stateful através da anotação @Stateful.
• Ela implementa a interface Cart (que é remota).
EJB – Bean de Sessão Stateful – Outro Exemplo (Bean)
public void initialize(String person) throws BookException {
if (person == null) {
throw new BookException("Null person not
allowed.");
}
else {
customerName = person;
}
customerId = "0";
contents = new ArrayList<String>();
}
...
• Devemos implementar os métodos de negócio, normalmente.
EJB – Bean de Sessão Stateful – Outro Exemplo (Bean)
@PostActivate
public void whenActivated() {
...
}
@PrePassivate
public void whenPassivate() {
...
}
...
• Podemos implementar métodos de ciclo de vida da bean, se necessário.
• Basta anotar métodos quaisquer com as anotações apropriadas.
EJB – Bean de Sessão Stateful – Outro Exemplo (Bean)
@Remove
public void remove() {
contents = null;
}
• Métodos anotados com a anotação @Remove podem ser chamados pelo cliente para remover uma bean.
• Quando isso ocorre, o cliente abre mão da bean.
• Container remove a bean.
EJB – Gerenciamento de Beans de Sessão
• O gerenciamento das beans de sessão pelo container depende do tipo de bean.
– Stateless.
– Stateful.
• Beans stateless tipicamente utilizam esquema de pool.
– Container instancia várias inicialmente e guarda os objetos em um pool.
– A medida que novas requisições são feitas para seu serviço JNDI, container devolve instâncias disponíveis no pool.
– Se o número de acessos simultâneos cresce, container pode acrescentar mais instâncias ao pool.
– Container também tem liberdade para decidir se pode/deve descartar instâncias.
EJB – Gerenciamento de Beans de Sessão (II)
• Beans Stateful tem gerenciamento diferente.
– Estão associadas aos clientes que a criaram.
– Por isso, são tipicamente criadas sob demanda.
– Mas o container pode manter um pool de instâncias também.
• Instâncias “semi-prontas”.
• Container só chama o método ejbCreate() (se houver), quando o cliente solicita a criação.
– De toda forma, container não pode simplesmente remover uma instância de uma bean stateful.
• Instância deve permanecer criada e associada a um cliente até que ela expire ou que o cliente chame o método remove().
EJB – Gerenciamento de Beans de Sessão (III)
• Beans Stateful também podem ser colocadas em memória secundária (Passivate) e trazidas de volta (Activate).
– Operações realizadas pelo container caso haja necessidade de liberar recursos (como memória).
• Quando uma bean é colocada em memória secundária, o container necessariamente chama o método ejbPassivate() da bean imediatamente antes.
– Ou o método anotado com a anotação @PrePassivate, se houver.
– Método deve liberar recursos não-serializáveis da bean.
EJB – Gerenciamento de Beans de Sessão (IV)
• Beans Stateless não são colocadas em memória secundária (e, por consequência, não são re-ativadas).
– Logo, não necessitam dos métodos ejbPassivate ou ejbActivate.
– Ou versões anotadas.
• O motivo é simples:
– Como elas não guardam estado e instâncias são intercambiáveis, container pode simplesmente destruir instâncias e criar novas quando necessário.
EJB – Suporte Transacional
• Um dos serviços fornecidos pelos containers EJB é o suporte a transações.
• Em geral, este suporte não é relevante às beans de sessão.
– Elas normalmente não representam dados persistentes compartilhados.
– E, no caso das beans stateful, só podem ser acessadas por um cliente por vez.
• Mas algumas vezes, beans de sessão stateful são utilizadas para intermediar o acesso a bases de dados remotas.
– Neste caso, é importante saber quando começa e termina uma transação.
– Clientes podem fazer diveras operações e quererem, ao final, dar um roll-back.
– Ou simplesmente um commit.
EJB – Suporte Transacional (II)
• Por isso, a API do EJB dá suporte a operações transacionais nas beans de sessão stateful.
• Para ter este suporte, a bean deve implementar a interface javax.ejb.SessionSynchronization.
• Ao realizar a implementação desta interface, a bean sinaliza ao container que quer ser avisada dos eventos de início e fim de uma transação.
• A interface requer implementação de 3 métodos:
– afterBegin(): chamado logo após o início de uma transação.
• Permite ao bean alocar recursos para atender à transação.
– beforeCompletion():
• Permite ao bean desalocar recursos.
– afterCompletion(boolean): determina se deve ser feito um commit ou um roll-back da operação.