por Ken Saks
O último update da tecnologia Enterprise JavaBeans (EJB), EJB 3.1, está próximo de ser finalizado. O
final draft da especificação já está disponível. O objetivo principal desta nova especificação é simplificar o desenvolvimento usando EJB e adicionar algumas funcionalidades há muito solicitadas, como os
singleton beans.
A versão 3.1 da especificação será incluída na JEE 6. Um
preview está disponível para
download. Esta versão inclui uma implementação quase completa da especificação EJB 3.1 e uma aplicação de exemplo que se beneficia de algumas das nova funcionalidades presentes na nova especificação.
Este
Tech Tip introduz um pouco dessas novas capacidades excitantes da EJB 3.1. Também inclui instruções de como rodar a aplicação exemplo presente no
preview
Facilidade de desenvolvimento
A EJB 3.1 é baseada nos componentes de fácil usabilidade da EJB 3.0, fornecendo muitas alternativas novas para aumentar a produtividade do desenvolvedor. A principal delas é a habilidade de implementar
session beans usando apenas uma classe
bean e a habilidade empacotar os
beans diretamente em um arquivo
war, sem a necessidade de um arquivo
ejb-jar.
No-interface View
O EJB 3.0
local client view é baseado em uma
Plain Old Java Interface (POJI) chamada de
local business interface. Uma interface local define os métodos de negócio que são expostos para o cliente a que serão implementados nas classes
bean. Apesar desta separação entre
interface e implementação ser uma abordagem bem aceita para
design de aplicações, a separação algumas vezes se torna uma complexidade desnecessária e adiciona pouco valor. Isto é verdade, especialmente, quando usamos componentes
fine-grained, com clientes muito acoplados que são colocados no mesmo módulo.
Desenvolvedores tem questionado uma forma de obter a mesma funcionalidade de
enterprise bean sem precisar escrever
business interfaces separadas. A especificação EJB 3.1 responde esse questionamento, tornando as
local business interface opcionais. O resultado é
no-interface local view.
A
no-interface view tem o mesmo comportamento da
local view da EJB 3.0, por exemplo, suporta funcionalidades como a chamada semântica por passagem por referência e propagação de transação e segurança. Entretanto,
no-interface view não requer uma interface separada, isto é, todos os métodos públicos da classe bean são expostos automaticamente para o cliente. Por default, qualquer
session bean que tem uma cláusula vazia
implements e não define nenhum outro
client view local ou remoto, expõe uma
no-interface client view.
Por exemplo, o
session bean a seguir expõe uma
no-interface view
@Stateless
public class HelloBean {
public String sayHello() {
String message = propertiesBean.getProperty("hello.message");
return message;
}
}
Como no caso para as local view, o cliente de uma no-interface view adquire uma referência EJB -- através de injeção ou JNDI lookup. A única diferença é que o tipo Java da referência EJB é a classe
bean, em vez de o tipo da local interface. Isto é mostrado no seguinte cliente
bean:
@EJB
private HelloBean helloBean;
...
String msg = helloBean.sayHello();
Note que mesmo que não seja uma
interface, o cliente não pode usar o operador
new() para instanciar explicitamente a classe
bean. Isto porque todas as invocações de bean são feitas através de uma referência especial, ou
proxy, fornecidas pelo
container. Isto permite ao
container fornecer todos os serviços adicionais de
bean, como
pooling, transações gerenciadas pelo
container e gerenciamento de concorrência.
Pacotes simplificados
A especificação EJB sempre necessita que os enterprise beans sejam empacotados em um módulo chamado arquivo
ejb-jar. Como isto é comum para aplicações web Java EE, para usar
enterprise beans, este requerimento de empacotamento pode ser penoso. Estas aplicações são forçadas a usar um
web application archive (arquivo
.war) para a aplicação web, um arquivo
ejb-jar para os
enterprise beans e um
enterprise archive (arquivo
.ear) que engloba os outros pacotes. Esta abordagem de empacotamento é complicada pelo suporte especial necessário para qualquer classes ou recursos que devem ser compartilhados entre os módulos.
A especificação EJB 3.1 endereça este problema removendo a restrinção de que classes
enterprise beans devem ser empacotadas em um arquivo
ejb-jar. Você agora tem a opção de colocar as classes EJB diretamente no arquivo
.war, utilizando a mesma orientação de empacotamento aplicada as classes
web applications. Isto significa que você pode colocar classes EJB sob o diretório
WEB-INF/classes ou em um arquivo
.jar no diretório
WEB-INF/lib. O EJB
deployment descriptor também é opcional. Se necessário, você pode empacota-lo como um arquivo
WEB-INF/ejb-jar.xml.
Novas funcionalidades na EJB 3.1
Devido ao foco concentrado na faciliadade de uso no EJB 3.0, não houve tempo suficiente para adicionar muitas outras funcionalidades requeridas pelos desenvolvedores. A especificação EJB 3.1 adiciona algumas dessas funcionalidades na API EJB. Quatro dessas novas funcionalidades são os
singleton session beans,
application initialization/shutdown callbacks,
invocações assíncronas de session beans e
automatic EJB timers.
Singleton
Uma omissão de muito tempo na API EJB foi a habilidade de facilmente compartilhar estado entre multiplas instâncias de um componente
enterprise bean ou entre multiplos componentes enterprise bean na aplicação. Em contraste, o modelo de programação web Java EE já provê esta tipo de capacidade através de um objeto
ServletConfig. Na EJB 3.1, esta omissão foi resolvida com a introdução dos
singleton beans, também conhecidos como
singletons.
Um
singleton é um novo tipo de
session bean que garante que haverá apenas uma instância para uma aplicação na JVM. Um singleton é definido usando a anotação
Singleton, como mostrado no seguinte exemplo:
@Singleton
public class PropertiesBean {
private Properties props;
private int accessCount = 0;
public String getProperty(String name) { ... }
public int getAccessCount() { ... }
}
Por ser somente outro tipo de
session bean, um singleton pode definir a mesma
client view, local ou remoto, como
stateless e
stateful bean.Clientes acessam os
singletons da mesma maneira que acessam
stateless e
stateful bean, isto é, através de uma referência EJB. Por exemplo, um cliente pode acessar o
singleton PropertiesBean, como segue:
@EJB
private PropertiesBean propsBean;
...
String msg = propsBean.getProperty("hello.message");
Aqui, o
container assegura que todas as invocações para todas as referências
PropertiesBean na mesma JVM são servidos pela mesma instância de
PropertiesBean. Por default, o
container força a mesma garantia de threading como para outros tipos de componentes. Especificamente, não mais que uma invocação é permitida para acessar uma instância particular do
bean, a qualquer momento. Para os
singletons, isto significa bloquear qualquer invocação concorrente. Entretanto, este é somente o comportamento concorrente padrão. Existem opções de concorrência que permitem acessos concorrentes mais eficientes para uma instância
singleton.
Application Startup/Shutdown Callbacks
A introdução dos
singletons também provê uma forma conveniente para as aplicações EJB receberem
callbacks durante a inicialização ou finalização da aplicação. Por default, o
container decide quando instanciar o
singleton. Entretanto, você pode forçar a instanciação do
singleton pelo
container durante a inicialização da aplicação, usando a anotação
@Startup. Isto permite ao
bean definir um método
@PostConstruct que garante ser chamado em tempo de inicialização. Adicionalmente, qualquer método
@PreDestroy para um
singleton será chamado na finalização da aplicação, independentemente se um
singleton foi instanciado usando
lazy instantiation ou
eager instantiation. Em uma
lazy instantiation, o
singleton não é instanciado até seus métodos serem necessários. Na
eager instatiation, o
singleton é instanciado na inicialização, não importando se será ou não usado.
Aqui está um exemplo que mostra uma parte de um
singleton que inclui uma anotação
@Startup, assim como métodos
@PostConstruct e
@PreDestroy:
@Singleton
@Startup
public class PropertiesBean {
@PostConstruct
private void startup() { ... }
@PreDestroy
private void shutdown() { ... }
...
}
Aplicação exemplo
O
Java EE 6 SDK Preview release inclui uma aplicação que usa cada uma das funcionalidade da EJB 3.1 cobertas neste tutorial. A aplicação é composta de um servlet, um singleton session bean e de um stateless session bean. Cada
session bean expõe uma
no-interface view. O
singleton define um
callback que é chamado pelo
container durante a inicialização da aplicação. Ambos, o
servlet e o
stateless bean, usam o singleton para acessar informações comuns de configuração da aplicação. Quando o
servlet é acessado, invoca ambos
session beans e imprime algumas mensagens contendo os valores retornados.
A aplicação inteira é empacotada em um arquivo
.war, sem nenhum arquivo
.xml.
Para rodar a aplicação de exemplo, faça o seguinte:
- Se você ainda não fez, baixe a Java EE 6
SDK Preview. Tenha certeza, também, de ter a Java Platform Standard Edition (Java SE) 6 SDK instalada.
- Baixe a aplicação exemplo, ejb31-war.war.
- Inicie o servidor de aplicações GlassFish V3 Prelude, que está no Java EE 6 SDK, digitando o seguinte comando:
javaee_home>/bin/asadmin start-domain
onde
<javaee_home> é onde o Java EE 6 SDK está instalado.
- Faça o deploy a aplicação exemplo, copiando-a parao diretório <javaee_home>/domains/domain1/autodeploy.
- Execute a aplicação, abrindo o browser e acessando a URL http://localhost:8080/ejb-ejb31-war
Você deverá ver a seguinte saída aparecendo no seu browser:
ejb31-war Servlet
HelloBean says : Hello, world
Singleton property access count = 2
Você pode ver o código fonte da aplicação em
<javaee_home>/samples/javaee6/ejb/ejb31-war/src.
Leituras adicionais