Session Bean
O Session Bean é um tipo de componente que executa a lógica de negócio da aplicação; por meio dele podem ser criados componentes que podem ser acessados por várias aplicações diferentes escritas em Java. E os session beans podem ser criados de duas formas: stateless e stateful, cada um com suas características que serão detalhadas a seguir.
Como o ciclo de vida de um componente EJB é controlado pelo Container EJB que existe no servidor web, não é possível criar um novo EJB através da palavra reservada new da linguagem Java, por exemplo:
MeuEJB ejb = new MeuEJB(); // ERRADO!!!
O código anterior compila e executa, mas não funciona corretamente, pois não foi criado pelo Container EJB, então não ganha todos os benefícios que o framework EJB disponibiliza para os componentes distribuídos. A forma correta é solicitar ao servidor web a criação de um componente, por exemplo:
InitialContext ctx = new InitialContext();
MeuEJB ejb = (MeuEJB) ctx.lookup("nomeComponente");
Deste modo, o componente EJB é instanciado dentro do Container EJB e assim ganhará todos os benefícios como uma conexão com o banco de dados, acesso a uma fila de mensageria, entre outros.
Stateless Session Bean
O Stateless Session Bean tem o ciclo de vida que dura apenas o tempo de uma simples chamada de método, sendo assim ao solicitar um componente deste tipo para o servidor web e executar o método desejado, este componente já pode ser destruído.
Quando é solicitado um Stateless Session Bean ao Container EJB, por meio do lookup(), ocorrem os seguintes passos:
- O Container EJB cria uma instância do Stateless Session Bean;
- Executa o método chamado;
- Se houver retorno no método, este objeto retornado é enviado para quem chamou o método do EJB;
- Depois o Container EJB destrói o objeto do componente EJB.
O Stateless também não mantém o estado entre as chamadas de método, deste modo, caso tenha algum atributo dentro do EJB este atributo é perdido toda vez que o EJB é chamado.
O problema do Stateless Session Bean e que a cada requisição um novo bean pode ser criado, por isso normalmente é configurado no container EJB, para gerar um pool de instâncias do EJB.
Um Stateless Session Bean é formado por uma interface Remota, Local, ou ambas, e mais uma implementação destas interfaces.
Quando a aplicação cliente do componente EJB está em outro servidor web ou é uma aplicação desktop, faz-se necessário a criação de uma interface Remota. Para isto, é necessário criar uma interface para o componente EJB e adicionar a anotação javax.ejb.Remote.
No exemplo, a seguir, será criada uma interface chamada ServicoRemote e adicionado a anotação @Remote para informar que será a interface remota de um componente EJB. Na interface de um EJB é declarada apenas a assinatura dos métodos que a implementação deste EJB precisa ter.
package metodista.pbc.ejb.exemplo;
import javax.ejb.Remote;
/**
* Interface remota para o EJB de Serviço.
*/
@Remote
public interface ServicoRemote {
/**
* Método utilizado para abrir uma solicitação
* para um aluno.
* @param tipoServico - Serviço que será aberto.
* @param aluno - Aluno que solicitou o serviço.
*/
public abstract void abrirServico(String tipoServico,
Aluno aluno);
}
Também há a opção de criar uma interface Local que é utilizada quando for necessário fazer uma chamada a um EJB que está no mesmo servidor web da aplicação cliente; para isto é necessário adicionar a anotação javax.ejb.Local na interface local.
No exemplo, a seguir, será criada uma interface chamada ServicoLocal e adicionado a anotação @Local para informar que ela será a interface local de um EJB. Na interface de um EJB é declarada a assinatura dos métodos que a implementação deste EJB precisa ter.
package metodista.pbc.ejb.exemplo;
import java.util.List;
import javax.ejb.Local;
/**
* Interface local para o EJB de serviço.
*/
@Local
public interface ServicoLocal {
/**
* Método utilizado para buscar todos os servicos
* de um aluno.
* @param aluno - Aluno que abriu os serviços.
* @return Lista de serviços de um aluno.
* @throws Exception
*/
public abstract List<Servico> buscarServicos(Aluno aluno)
throws Exception;
}
Mesmo criando uma interface remota o componente EJB pode ser acessado localmente, então escolher entre Remoto e Local vai muito da situação. Se precisar acessar o componente apenas dentro do mesmo servidor web vale a pena deixar Local, mas se houver a necessidade de utilizar em outras aplicações distribuídas em vários servidores então é preciso criar a interface remota.
Também é necessário criar uma classe que implemente uma ou ambas interfaces. Para que esta classe seja reconhecida pelo Container EJB, como um EJB Session Bean do tipo Stateless, é necessário adicionar a anotação javax.ejb.Stateless.
No exemplo, a seguir, foi criada uma classe ServicoBean que implementa a interface ServicoRemote; note a anotação @Stateless que define o tipo deste EJB como Stateless Session Bean:
package metodista.pbc.ejb.exemplo;
import javax.ejb.Stateless;
/**
* Stateless session bean que implementa as funcionalidades
* referentes a interface remota.
*/
@Stateless
public class ServicoBean implements ServicoRemote {
/**
* Método utilizado para abrir uma solicitação para um aluno.
* @param tipoServico - Serviço que será aberto.
* @param aluno - Aluno que solicitou o serviço.
*/
public void abrirServico(String tipoServico, Aluno aluno) {
/* Código que abre a solicitação de serviço para um aluno. */
}
}
Stateful Session Bean
O Stateful session bean é bem parecido com o Stateless. A diferença é que ele pode viver no container EJB enquanto a sessão do usuário estiver ativa, portanto a partir do momento em que o componente é chamado pelo cliente, ele passa a ser exclusivamente do cliente que o chamou até que o cliente deixe a aplicação.
Outra diferença fundamental é que ele mantém o estado durante as chamadas dos métodos preservando os valores das variáveis.
O problema do Stateful Session Bean é que pode haver um número muito grande de instâncias na memória do servidor por ser associado a um único cliente, portanto cada vez que um cliente conecta a aplicação e precisa usar este tipo de EJB, um novo objeto EJB é criado para atendê-lo; desta forma se for necessário é possível manter o estado dos atributos do EJB para diversas chamadas de métodos feitas nele.
A implementação do Stateful também é muito parecida com a implementação do Stateless, a única diferença é que a classe do tipo Stateful utiliza a anotação javax.ejb.Stateful.
No exemplo, a seguir, é criada uma classe chamada ServicoBean que implementa a interface ServicoRemote, note a anotação @Stateful que define o tipo deste EJB como Stateful Session Bean:
package metodista.pbc.ejb.exemplo;
import javax.ejb.Stateful;
/**
* Stateful session bean que implementa as funcionalidades
* referentes a interface remota.
*/
@Stateful
public class ServicoBean implements ServicoRemote {
/**
* Método utilizado para abrir uma solicitação para um aluno.
* @param tipoServico - Serviço que será aberto.
* @param aluno - Aluno que solicitou o serviço.
*/
public void abrirServico(String tipoServico, Aluno aluno) {
/* Código que abre a solicitação de serviço para um aluno. */
}
}
Também é possível fazer um pool de Stateful Session Bean, mas alguns problemas podem ocorrer, como, por exemplo, acabar a memória do servidor. Para limitar a quantidade de instâncias na memória o container EJB pode guardar o estado da conversa (valor dos atributos do EJB) no HD ou em base de dados, isto é chamado de passivation.
Quando o cliente original do bean fizer uma requisição para um componente que foi guardado, o Container EJB traz o objeto EJB de volta para a memória, isto é chamado de activation.
Uma coisa importante é que quando o bean faz parte de uma transação, este bean não pode passar por passivation até terminar a transação.
A figura a seguir mostra o fluxo de uma chamada feita por um cliente remoto ou cliente local a um componente EJB.
Modelo de programação EJB 3.0 (BROSE, G.; SILVERMAN, M.; SRIGANESH, R. P., 2006, p.106)