domingo, 23 de agosto de 2009

Uma amostragem da EJB 3.1 (Tradução)

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:
  1. 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.
  2. Baixe a aplicação exemplo, ejb31-war.war.
  3. 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.
  1. Faça o deploy a aplicação exemplo, copiando-a parao diretório <javaee_home>/domains/domain1/autodeploy.
  2. 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

Nenhum comentário:

Postar um comentário