Introdução ao EJB 3.0 e os Enterprise Bean Components – Parte II

Leia a Parte I.

Interfaces remotas

Para tornar accessível remotamente uma session bean, é necessário apenas designá-la com @Remote, tal como a seguir:


@Stateless
@Remote
public classe MusicStore implementa IMusicStore
{
    ...
}

No exemplo acima, o MusicStore bean implementa uma interface de negócio; assume-se que seja remota pois uma classe foi designada como remota. No caso em que o MusicStore implemente mais de uma interfaces de negócio, seria necessário especificar quais interfaces são locais e quais são remotas. Podemos especificar isto de duas maneiras: em uma classe ou em uma interface. Para mudar uma classe MusicStore para que utilize uma interface remota, faríamos o seguinte:


@Stateless
@Local( { IMusicStore.classe } )
@Remote( { IMusicStoreRemote.classe } )
public classe MusicStore implementa IMusicStore, IMusicStoreRemote
{
    ...
}

Comparando o método acima com o especificado em uma interface:


@Remote
public interface IMusicStoreRemote
{
    ...
}

Notamos que a interface remota não levanta RemoteExceptions. Caso aconteça alguma exceção em nível de protocolo, então um EJBException “envelopando” o RemoteException será levantado pelo recipiente (container). Tal como uma RuntimeException, o EJBException não necessita ser declarado na assinatura do método de uma interface remota ou na sua classe bean de implementação.

Session beans com estado

Session beans com estado têm requisitos muito semelhantes aos dos session beans sem estado: devem ter ao menos uma interface de negócio. No entanto, são apropriadamente designadas com @Stateful. No exemplo music store, o cartão de compras do usuário foi modelado como uma session bean com estado, pois representa uma troca de mensagens com estado entre um usuário e o servidor:


@Stateful
public classe ShoppingCart implementa IShoppingCart
{
    ...
}

Assim como no EJB 2.x, invocações para uma mesma referência em uma session bean com estado são tratadas pelo mesma instância EJB, sendo importante armazenar esta referência em um local que possa ser repetidamente lido pelo cliente. No caso do music store, esta referência é armazenada na HttpSession do usuário.

Beans orientados a mensagem

Beans orientados a mensagem (Message Driven Beans - MDBs) também implementam uma interface de negócio e são designadas para indicar seu tipo bean. Neste caso, no entanto, a interface de negócio não veio do domínio, é uma interface listener apropriada para o tipo de sistema de mensagens que está sendo utilizado. No caso do JMS, é uma javax.jms.MessageListener. O processador de pedidos do music store provê um exemplo:


@MessageDriven
public classe OrderProcessor implementa MessageListener
{
    public void onMessage(Message message)
    {
        ObjectMessage objectMessage = (ObjectMessage) message;

        try
        {
            Order order = (Order) objectMessage.getObject();

            System.out.println("Products Ordered:");

            para (Product p : order.getProducts())
            {
                System.out.println(p.getTitle());
            }
        }
        catch (JMSException e)
        {
            e.printStackTrace();
        }
    }
}

Assim como com o EJB 2.x, podemos fornecer informação adicional para o distribuidor sobre como o MDB deve ser configurado. Esta informação poderá então ser fornecida via um elemento activationConfig da designação @MessageDriven. Por exemplo, para definir que o OrderProcessor é ativado apenas para as mensagens JMS chegando da fila de pedidos, poderíamos designar uma classe como a seguir:


@MessageDriven(activateConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/orders")
})
public classe OrderProcessor implementa MessageListener
{
    ...
}

Porém, como com versões prévias do EJB, o distribuidor ainda tem a responsabilidade de associar um MDB com um destino ou ponto final (endpoint).

Empacotando e distribuindo

O empacotamento no EJB 3.0 tem muitas semelhanças com o empacotamento nas versões prévias do EJB. Assim como com as versões prévias, as classes enterprise bean devem ser empacotadas em um arquivo .JAR. A grande diferença é que com o release EJB 3.0, o descritor de distribuição é opcional. No entanto, caso um seja fornecido, então deverá constar no seu lugar usual (META-INF/ejb-jar.xml).

Nota: no JBoss EJB 3.0, os jars tem a extensão .ejb3 — uma convenção Jboss, porém não um requisito da especificação.

Para distribuir a aplicação, apenas copiamos o arquivo .EAR resultante para o diretório de distribuição de um servidor JBoss 4.0.3, configurado com o distribuidor JBoss AOP 1.3.4.

Boas vindas para um modelo simplificado

O projeto público do EJB 3.0 traz um modelo drasticamente simplificado para codificação de componentes empresariais. Este novo paradigma simplifica o desenvolvimento e introduz poucas novas funcionalidades além das anteriormente disponíveis. Mesmo assim, as simplificações oferecidas pelo EJB 3.0 deverão otimizar significantemente a produtividade das equipes. Será interessante ver como esta nova implementação leve irá se comportar com relação a outros frameworks tais como o Spring e o Hibernate.