SeamFramework.orgCommunity Documentation
Derzeit läuft die Web Beans RI nur in JBoss AS 5; die Implementierung der RI in andere EE-Umgebungen (zum Beispiel einen anderen Applikationsserver wie Glassfish) in einen Servlet-Container (wie Tomcat) oder eine Embedded EJB3.1 Implementierung ist recht einfach. In diesem Anhang gehen wir kurz auf die notwendigen Schritte ein.
Es sollte möglich sein, Web Beans in einer SE Umgebung auszuführen, aber Sie werden mehr Arbeit durchführen müssen indem Sie Ihre eigenen Kontexte und Lebenszyklus hinzufügen. Die Web Beans RI legt derzeit keine Lebenszyklus-Erweiterungspunkte offen, weswegen Sie direkt gegen Web Beans RI-Klassen kodieren müssten.
Das Web Beans SPI befindet sich im webbeans-ri-spi
-Modul und ist als webbeans-ri-spi.jar
verpackt. Einige SPIs sind optional, wenn Sie das standardmäßige Verhalten außer Kraft setzen möchten, sind andere erforderlich.
Alle Interfaces im SPI unterstützen das Dekorator-Muster und liefern eine Forwarding
-Klasse.
public interface WebBeanDiscovery {
/**
* Gets list of all classes in classpath archives with web-beans.xml files
*
* @return An iterable over the classes
*/
public Iterable<Class<?>
> discoverWebBeanClasses();
/**
* Gets a list of all web-beans.xml files in the app classpath
*
* @return An iterable over the web-beans.xml files
*/
public Iterable<URL
> discoverWebBeansXml();
}
Die Discovery von Web Bean Klassen und web-bean.xml
Dateien versteht sich von selbst (der Algorithmus wird in Abschnitt 11.1 der JSR-299 Spezifikation beschrieben, weswegen hier nicht darauf eingegangen wird).
Die Web Beans RI delegiert auch EJB3 Bean Discovery an den Container, so dass er nicht nach EJB3-Annotationen scannen oder ejb-jar.xml
parsen muss. Für jedes EJB in der Anwendung sollte der EJBDescriptor aufgefunden werden:
public interface EjbDiscovery
{
public static final String PROPERTY_NAME = EjbDiscovery.class.getName();
/**
* 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();
}
Der EjbDescriptor
ist recht leicht verständlich und sollte relevante Metadaten wie in der EJB-Spezifikation definiert wiedergeben. Neben diesen beiden Interfaces existiert ein BusinessInterfaceDescriptor
, der ein lokales Business-Interface repräsentiert (die Interface-Klasse und den für die Suche einer Instanz des EJB verwendeten jndi-Namens enthaltend).
Die Auflösung von @EJB
, @PersistenceContext
und @Resource
wird an den Container delegiert. Sie müssen eine Implemntierung von org.jboss.webbeans.ejb.spi.EjbResolver
bereitstellen, die diese Operationen liefert. Web Beans gibt an den javax.inject.manager.InjectionPoint
weiter für den die Auflösung ist sowie den für jede Auflösungsanfrage verwendeten NamingContext
.
The Web Beans RI must delegate JTA activities to the container. The SPI provides a couple hooks to easily achieve this with the TransactionServices
interface.
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();
}
The enumeration Status
is a convenience for implementors to be able to keep track of whether a synchronization is supposed to notify an observer only when the transaction is successful, or after a failure, or regardless of the status of the transaction.
Any javax.transaction.Synchronization
implementation may be passed to the registerSynchronization()
method and the SPI implementation should immediately register the synchronization with the JTA transaction manager used for the EJBs.
To make it easier to determine whether or not a transaction is currently active for the requesting thread, the isTransactionActive()
method can be used. The SPI implementation should query the same JTA transaction manager used for the EJBs.
Web Beans erwartet, dass der Applikations-Server oder anderer Container den Speicher für den Kontext jeder Applikation bereitstellt. Der org.jboss.webbeans.context.api.BeanStore
sollte implementiert sein, um einen durch die Applikation begrenzten Speicher bereitzustellen. Vielleicht finden Sie in diesem Zusammenhang org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore
hilfreich.
Das org.jboss.webbeans.bootstrap.api.Bootstrap
-Interface definiert den Bootstrap für Web Beans. Um Web Beans zu booten müssen Sie eine Instanz von org.jboss.webbeans.bootstrap.WebBeansBootstrap
erhalten (die Boostrap
implementiert), diese über die verwendeten SPIs informieren und dann beim Container um Start anfragen.
Der Bootstrap ist in Phasen aufgeteilt, Bootstrap Initialisierung und Bootstrap. Die Initialisierung erstellt einen Manager und fügt die Standard-Kontexte (spezifikationsdefiniert) hinzu. Bootstrap findet EJBs, Klassen und XML auf; fügt unter Verwendung von Annotationen definierte Beans hinzu; fügt unter Verwendung von XML definierte Beans hinzu; und validiert alle Beans.
Zur Initialisierung des Bootstrap rufen Sie Bootstrap.initialize()
auf. Ehe Sie initialize()
aufrufen, müssen Sie Bootstrap.setEjbResolver()
aufgerufen haben. Falls Sie nicht den eingebauten DefaultNamingContext
oder den eingebauten DefaultResourceLoader
verwenden, so müssen Sie diese setzen, ehe Sie initialize()
aufrufen.
Nach Aufruf von initialize()
erhalten Sie den Manager
durch Aufruf von Bootstrap.getManager()
.
Zum Booten des Containers rufen Sie Bootstrap.boot()
auf. Ehe Sie boot()
aufrufen, müssen Sie Bootstrap.setWebBeanDiscovery()
, Bootstrap.setEjbDiscovery()
und Bootstrap.setApplicationContext()
aufgerufen haben.
Um den Container herunterzufahren, rufen Sie you call Bootstrap.shutdown()
auf. Dies gestattet es dem Container notwendige Bereinigungsvorgänge durchzuführen.
Die Web Beans RI implementiert JNDI-Binding und Lookup gemäß Standards, jedoch möchten Sie vielleicht Binding und Lookup ändern (etwa in einer Umgebung, in der JNDI nicht verfügbar ist). Um dies zu tun, implementieren Sie org.jboss.webbeans.resources.spi.NamingContext
:
public interface NamingContext extends Serializable {
/**
* Typed JNDI lookup
*
* @param <T
> The type
* @param name The JNDI name
* @param expectedType The expected type
* @return The object
*/
public <T
> T lookup(String name, Class<? extends T
> expectedType);
/**
* Binds an item to JNDI
*
* @param name The key to bind under
* @param value The item to bind
*/
public void bind(String name, Object value);
}
Die Web Beans RI muss Klassen und Ressourcen zu verschiedenen Zeiten aus dem Klasspfad laden. Standardmäßig werden diese aus demselben Klasslader geladen, der zum laden der RI verwendet wurde, allerdings ist das möglicherweise nicht geeignet für einige Umgebungen. Ist dies der Fall, so können Sie org.jboss.webbeans.spi.ResourceLoader
implementieren:
public interface ResourceLoader {
/**
* Creates a class from a given FQCN
*
* @param name The name of the clsas
* @return The class
*/
public Class<?> classForName(String name);
/**
* Gets a resource as a URL by name
*
* @param name The name of the resource
* @return An URL to the resource
*/
public URL getResource(String name);
/**
* Gets resources as URLs by name
*
* @param name The name of the resource
* @return An iterable reference to the URLS
*/
public Iterable<URL
> getResources(String name);
}
Java EE / Servlet does not provide any hooks which can be used to provide injection into Servlets, so Web Beans provides an API to allow the container to request JSR-299 injection for a Servlet.
To be compliant with JSR-299, the container should request servlet injection for each newly instantiated servlet after the constructor returns and before the servlet is placed into service.
To perform injection on a servlet call WebBeansManager.injectServlet()
. The manager can be obtained from Bootstrap.getManager()
.
Es gibt eine Reihe von Voraussetzungen, die Web Beans RI dem Container für das korrekte Funktionieren von Implementierungen auferlegen, die außerhalb von Implementierung von APIs fallen.
Falls Sie die Web Beans RI in eine Umgebung integrieren, die das Deployment mehrerer Anwendungen unterstützt, so müssen Sie automatisch oder über Benutzerkonfiguration die Klassenlader-Isolierung für jede Web Beans Anwendung aktivieren.
Falls Sie Web Beans in eine Servlet Umgebung integrieren, müssen Sie org.jboss.webbeans.servlet.WebBeansListener
als einen Servlet-Listener registrieren, entweder automatisch oder aber durch Benutzerkonfiguration. Dies muss für jede Servlet benutzende Web Beans Applikation erfolgen.
If you are integrating the Web Beans into a JSF environment you must register org.jboss.webbeans.servlet.ConversationPropagationFilter
as a Servlet listener, either automatically, or through user configuration, for each Web Beans application which uses JSF. This filter can be registered for all Servlet deployment safely.
Falls Sie Web Beans in eine EJB Umgebung integrieren, müssen Sie org.jboss.webbeans.ejb.SessionBeanInterceptor
als einen EJB-Interzeptor für alle EJBs in der Applikation registrieren, entweder automatisch oder aber durch Benutzerkonfiguration. Dies muss für jede Enterprise Beans benutzende Web Beans Applikation erfolgen.
You must register the SessionBeanInterceptor
as the inner most interceptor in the stack for all EJBs.
webbeans-ri.jar
Falls Sie Web Beans in eine Umgebung integrieren, die das Deployment von Anwendungen unterstützt, so müssen Sie die webbeans-ri.jar
in den isolierten Klassenlader der Anwendungen einfügen. Das Laden kann nicht aus einem geteilten Klassenlader erfolgen.