Spring em Seam, Parte 2: Quando há colisão entre stateless e stateful – Etapa 04

por: Dan Allen


Doando Componentes Seam para o Container do Spring

Tudo o que fizemos até o momento foi pegar, pegar, pegar. Agora já é hora de darmos um pouco ao Spring. Após tudo isso, se os componentes Spring são úteis para o Seam, então a recíproca provavelmente é verdadeira. A tag <seam:instance> funciona para qualquer componente Seam, não apenas para componentes híbridos Spring-Seam. Mais aqui está o pulo do gato: a tag <seam:instance> pode também ser usada para injetar o resultado da expressão de valor de uma EL (linguagem de expressão) na propriedade de um bean Spring! Isso nos dá a possibilidade do Seam poder contribuir com os beans Spring virtualmente sem limites.

Você pode pensar na tag <seam:instance> como uma alternativa para a anotação @In a partir da bijeção, particularmente quando o atributo Proxy é configurado como verdadeiro. O atributo name pode ser ou o nome de uma variável de contexto ou uma expressão de valor. O atributo scope limita a busca para a variável de contexto em um escopo simples. Se o atributo scope é excluído, então uma busca no contexto hierárquico será realizada. (Note que neste caso, o escopo está sendo interpretado pelo Seam para realizar uma busca, desta forma não usamos o prefixo de escopo citado anteriormente). Se o atributo create é especificado, e seu valor é true (verdadeiro), uma nova instância do componente será criada caso nenhuma ainda exista. Se este valor não for usado ou se ele for falso, uma nova instância não será alocada se um valor não tiver sido ainda associado à variável de contexto. Fazer uma re-chamada às expressões de valor implica que a flag create é true, apesar de tudo. O atributo proxy é a chave para prevenir impedância de escopo, mas mantenha em mente que ele adiciona uma pouco de sobrecarga extra à aplicação.

Configurar uma declaração <seam:instance> para um componente pode não ser tão ruim se tivermos que fazer isso apenas uma vez, mas se tivermos que redigitar a declaração cada vez que desejarmos injetar um dado componente Seam pode ser muito chato, sem mencionar a possibilidade de erro e falta de transparência. Isso ocorre porque a tag <seam:instance> foi projetada para se comportar como uma tag alias. Quando usado como um elemento de alto nível, o atributo id da tag <seam:instance> pode ser usado para criar um bean mediador. Para o container Spring, este bean é apenas como qualquer outro bean Spring. Em baixo nível, o elemento <seam:instance> resulta na criação de um SeamFactoryBean, que funciona apenas como um outro factory bean do Spring no qual o objeto de destino subjacente é tratado quando o factory bean é injetado. Neste caso, o que é injetado é um Proxy de componente Seam. A Listagem 9 apresenta exemplos de como todas as referências usadas neste artigo podem ser convertidas em alias e injetadas no bean singleton tournamentManager que está  no escopo da aplicação sem temer problemas de impedância de escopo ou segurança de thread.

 

Listagem 9. Definindo e usando alisas para proxies de componentes

<bean id="tournamentSearchCriteriaTarget"

  class="org.open18.partner.business.TournamentSearchCriteria"

  scope="seam.CONVERSATION"/>

 

<seam:instance id="tournamentSearchCriteria" name="tournamentSearchCriteriaTarget" proxy="true"/>

 

<seam:instance id="currentUser" name="#{currentUser}" proxy="true"/>

 

<seam:instance id="selectedTournament" name="selectedTournament" proxy="true"/>

 

<bean id="tournamentManager"

  class="org.open18.partner.business.impl.TournamentManagerImpl"

  scope="seam.APPLICATION">

  <property name="tournamentSearchCriteria" ref="tournamentSearchCriteria"/>

  <property name="selectedTournament" ref="selectedTournament"/>

  <property name="currentUser" ref="currentUser"/>

</bean>


Através da configuração de um alias, estamos livres para injetar o componente nas propriedades de outros beans Spring usando a tag <ref>, que é um jeito muito interessante de injetar um componente Seam de forma despercebida, possivelmente mais do que quando é usado proxy. Esse padrão de utilização, para alguns, é a melhor forma de prevenir erros e evitar impedância de escopo. Uma recomendação poderia ser a criação de um arquivo de configuração do Spring separado para contem essas definições de alias. Isso tornaria mais simples para realizar testes funcionais nos POJO’s do Spring (Ver Nota DevMan 1) na ausência do container Spring, pois o arquivo principal não possuirá referências <seam:instance> espalhadas por todos os lugares. Você pode facilmente trocas as implementações dos beans referenciados. Isso é uma espécie de POXD (plain old XML document).

 

Nota DevMan 1. POJO (Plain Old Java Object)

POJO é um acrônimo para Plain Old Java Object, e é favorecido pelos defensores da idéia de que quanto mais simples for o projeto, melhor. O nome é usado para enfatizar que o objeto em questão é um Objeto Java ordinário, não um objeto especial, e em particular não é um Enterprise JavaBean (especialmente antes do EJB 3). O termo foi definido por Martin Fowler, Rebecca Parsons e Josh MacKenzie em Setembro de 2000:

 

"Queremos saber por que pessoas são tão contra o uso de objetos simplificados em seus sistemas e concluímos que é faltava um nome fantasia para esses objetos simples. Então, demos um nome a eles, e ele caiu muito bem."

 

O termo segue o padrão de termos antigos para tecnologias que não usam novas funcionalidades fantasias, tais como POTS (Plain Old Telephone Service) em telefonia e PODS (Plain Old Data Structures) que é definido em C++ mas é usado somente em funcionalidades da linguagem C.

 

O termo tem ganhado mais aceitação por causa da necessidade de um termo comum e de simples entendimento que contraste com os complicados frameworks de objeto. Um JavaBean é um POJO que é serializável, possui um construtor sem argumento e permite acessar as propriedades usando métodos GET e SET. um Enterprise JavaBean não é uma simples class mas um modelo componente inteiro (novamente, EJB 3 reduz a complexidade dos Enterprise JavaBeans).

 

Como o projeto usando POJOs tem se tornado comumente usado, os sistemas que tem surgido dando aos POJOs algumas das funcionalidades usadas em frameworks e mais escolhas sobre quais áreas de funcionalidades são realmente necessárias. Hibernate e Spring são exemplos disso. O equivalente ao POJO no framework.NET é Plain Old CLR Object (POCO).

 

Variações Contextuais

 

O termo "POJO" é usado para denotar um objeto Java que não segue qualquer modelo de objeto Java principal, convenções ou frameworks tais como EJB.

Todos os objetos Java são POJOs, portanto idealmente podemos falar que um POJO é um objeto Java não limitado por qualquer restrição que não seja aquelas forçadas pela Especificação da Linguagem Java, ou seja, um POJO não pode ter:

 

-    Classes pré-especificadas estendidas, como em public class Foo extends javax.servlet.http.HttpServlet { ...

-    Interfaces pré-especificas omplementadas, como em public class Bar implements javax.ejb.EntityBean { ...

 

-    Anotações pré-especificas contidas, como em @javax.ejb.Entity public class Baz{ ...

 

No entanto, devido às dificuldades técnicas e outras razões, muitos produtos de software ou frameworks se descrevem como conforme ao POJO (POJO-compliant) apesar de ainda requerer o uso de anotações pré-especificadas para funcionalidades tal como persistência para funcionarem corretamente.