SeamFramework.orgCommunity Documentation

Appendice A. Integrazione di Web Beans RI in altri ambienti

Attualmente Web Bean RI funziona solo in JBoss AS 5; l'integrazione di RI in altri ambienti EE (per esempio in un application server come Glassfish), in un servlet container (come Tomcat), o con un'implementazione EJB3.1 Embedded è abbastanza facile. In questo appendice si discuterà brevemente dei passi necessari.

Nota

Dovrebbe essere possibile far funzionare Web Beans in un ambiente SE, ma occorre molto lavoro per aggiungere i propri contesti ed il ciclo di vita. Web Beans RI attualmente non espone punti di estensione del ciclo di vita, così occorre codificare direttamente nelle classi Web Beans RI.

The Web Beans SPI is located in webbeans-spi module, and packaged as webbeans-spi.jar. Some SPIs are optional, if you need to override the default behavior, others are required.

Tutte le interfacce in SPI supportano il pattern decorator e forniscono una classe Forwarding.

Web Beans RI delega al container la rilevazione dei bean EJB3 e quindi risulta non essere necessario eseguire lo scan delle annotazioni EJB3 o fare il parsing di ejb-jar.xml. Per ciascun EJB nell'applicazione dovrebbe essere rilevato un EJBDescriptor:

public interface EjbServices

{
   
   /**
    * Gets a descriptor for each EJB in the application
    * 
    * @return The bean class to descriptor map 
    */
   public Iterable<EjbDescriptor<?>
> discoverEjbs();
public interface EjbDescriptor<T

> {
   
   /**
    * Gets the EJB type
    * 
    * @return The EJB Bean class
    */
   public Class<T
> getType();
   /**
    * Gets the local business interfaces of the EJB
    * 
    * @return An iterator over the local business interfaces
    */
   public Iterable<BusinessInterfaceDescriptor<?>
> getLocalBusinessInterfaces();
   
   /**
    * Gets the remote business interfaces of the EJB
    * 
    * @return An iterator over the remote business interfaces
    */
   public Iterable<BusinessInterfaceDescriptor<?>
> getRemoteBusinessInterfaces();
   
   /**
    * Get the remove methods of the EJB
    * 
    * @return An iterator over the remove methods
    */
   public Iterable<Method
> getRemoveMethods();
   /**
    * Indicates if the bean is stateless
    * 
    * @return True if stateless, false otherwise
    */
   public boolean isStateless();
   /**
    * Indicates if the bean is a EJB 3.1 Singleton
    * 
    * @return True if the bean is a singleton, false otherwise
    */
   public boolean isSingleton();
   /**
    * Indicates if the EJB is stateful
    * 
    * @return True if the bean is stateful, false otherwise
    */
   public boolean isStateful();
   /**
    * Indicates if the EJB is and MDB
    * 
    * @return True if the bean is an MDB, false otherwise
    */
   public boolean isMessageDriven();
   /**
    * Gets the EJB name
    * 
    * @return The name
    */
   public String getEjbName();
   
   
}

Il EjbDescriptor è abbastanza auto-esplicatorio e dovrebbe restituire i metadati rilevanti definiti nella specifica EJB. In aggiunta a queste due interfacce, vi è BusinessInterfaceDescriptor a rappresentare un'interfaccia locale di business (che incapsula la classe d'interfaccia ed il nome jndi usato per la ricerca di una istanza EJB).

La risoluzione di @EJB e @Resource è delegata al container. Occorre fornire un'implementazione di org.jboss.webbeans.ejb.spi.EjbServices che rende disponibili queste operazioni. Web Beans passa nel javax.inject.manager.InjectionPoint la risoluzione, anche come NamingContext, che è in uso per ogni richiesta di risoluzione.

Web Beans RI deve delegare le attività JTA al container. SPI fornisce un paio di modi per ottenere ciò tramite l'interfaccia TransactionServices.

public interface TransactionServices

{
   /**
    * Possible status conditions for a transaction. This can be used by SPI
    * providers to keep track for which status an observer is used.
    */
   public static enum Status
   {
      ALL, SUCCESS, FAILURE
   }
   /**
    * Registers a synchronization object with the currently executing
    * transaction.
    * 
    * @see javax.transaction.Synchronization
    * @param synchronizedObserver
    */
   public void registerSynchronization(Synchronization synchronizedObserver);
   /**
    * Queries the status of the current execution to see if a transaction is
    * currently active.
    * 
    * @return true if a transaction is active
    */
   public boolean isTransactionActive();
}

La enumeration Status serve agli implementatori per poter essere in grado di tracciare se una sincronizzazione deve notificare un osservatore solo quando la transazione ha avuto successo, o dopo un errore, o indipendentemente dallo stato della transazione.

Qualsiasi implementazione di javax.transaction.Synchronization può essere passata al metodo registerSynchronization() e l'implementazione SPI deve immediatamente registrare la sincronizzazione con il gestore della transazione JTA usato per EJB.

Per facilitare la determinazione se o no una transazione è attualmente attiva per il thread di richiesta, può essere usato il metodo isTransactionActive(). L'implementazione SPI deve interrogare lo stesso gestore della transazione JTA usato per EJB.

L'interfaccia org.jboss.webbeans.bootstrap.api.Bootstrap definisce il bootstrap per Web Beans. Per avviare Web Beans occorre ottenere un'istanza di org.jboss.webbeans.bootstrap.WebBeansBootstrap (che implementa Boostrap), e comunicare le SPI in uso, e poi chiedere che il container venga avviato.

Il bootstrap è suddiviso in più fasi, inizializzazione del bootstrap, bootstrap e shutdown. L'inizializzazione creerà un manager, e aggiungerà i contesti standard (definiti dalla specifica). Bootstrap scoprirà EJB, classi e XML; aggiungerà i bean definiti con le annotazioni; aggiungerà i bean definiti con XML; e validerà tutti i bean.

Il bootstrap supporta più ambienti. Diversi ambienti richiedono diversi servizi presenti (per esempio servlet non richiede i servizi di transazione, EJB o JPA). Di default viene assunto un ambiente EE, ma si può impostare un ambiente chiamando bootstrap.setEnvironment().

Per inizializzare il bootstrap si chiama Bootstrap.initialize(). Prima della chiamata di initialize() occorre registrare i servizi richiesti dal proprio ambiente. Si può fare questo chiamando bootstrap.getServices().add(JpaServices.class, new MyJpaServices()). Occorre anche fornire l'application context bean store.

Dopo aver chiamato initialize(), il Manager può essere ottenuto chiamando Bootstrap.getManager().

Per avviare il container chiamare Bootstrap.boot().

Per spegnere il container si chiama Bootstrap.shutdown(). Questo consente al container di eseguire ogni pulizia necessaria delle operazioni.

Per il corretto funzionamento al di fuori dell'implementazione delle API, ci sono un numero di requisiti che Web Beans RI pone nel container.

Isolamento del classloader

Se si integra Web Beans in un ambiente che supporta il deploy di applicazioni, occorre abilitare, automaticamente o attraverso la configurazione utente, l'isolamento del classloader per ogni applicazione Web Beans.

Servlet listener e filtri

Se si integra Web Beans in un ambiente Servlet occorre registrare org.jboss.webbeans.servlet.WebBeansListener come Servlet listener, o automaticamente, o attraverso una configurazione utente, per ciascuna applicazione Web Beans che usa Servlet.

Se si integra Web Beans in un ambiente Servlet occorre registrare org.jboss.webbeans.servlet.ConversationPropagationFilter come Servlet listener, o automaticamente, o attraverso una configurazione utente, per ciascuna applicazione Web Beans che usa JSF. Questo filtro può venir registrato in modo sicuro per tutti i deploy dei servlet.

Session Bean Interceptor

Se si integra Web Beans in un ambiente EJB occorre registrare org.jboss.webbeans.ejb.SessionBeanInterceptor come interceptor EJB per ogni EJB dell'applicazione, o automaticamente o attraverso una configurazione utente, per ciascuna applicazione Web Beans che utilizza bean enterprise.

webbeans-core.jar

Se si integra Web Beans in un ambiente che supporta il deploy di applicazioni, occorre inserire webbeans-core.jar nel classloader isolato delle applicazioni. Non può essere caricato da un classloader condiviso.