SeamFramework.orgCommunity Documentation
目前,Web Bean RI 只能在 JBoss AS 5 中執行;要將 RI 整合入其它 EE 環境中(比方說另一個像是 Glassfish 的應用程式伺服器)、整合入一個 servlet 容器(例如 Tomcat)中,或是和一個崁入式的 EJB3.1 實做整合都是相當容易的。在此附錄中,我們將簡略地討論所需的步驟。
您可在一個 SE 環境下執行 Web Bean,不過您必須進行較多步驟,包括新增您自己的 context 和生命週期。Web Bean RI 目前並不會顯示生命週期的延伸點,因此您必須針對於 Web Bean RI 的 class 來直接地進行程式撰寫。
Web Bean SPI 位於 webbeans-ri-spi
模組中,並且被封裝為 webbeans-ri-spi.jar
。有些 SPI 為可選的,若您需要置換預設的特性,您則需要其它 SPI。
您可將一個 SPI 的實做作為系統內容來指定,或是在內容檔案 META-INF/web-beans-ri.properties
中來指定。所有內容名稱皆為已實做介面的完整類別(class)名稱,並且所有內容值皆為已實做類別的完整類別名稱。
SPI 中所有的介面都支援裝飾器模式並提供了一個 Forwarding
class。
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();
}
Web Bean 類別和 web-bean.xml
檔案的搜尋相當明顯(演算法描述於 JSR-299 規格的章節 11.1 中,在此不重複)。
Web Beans RI 可被指定來透過使用 org.jboss.webbeans.bootstrap.spi.WebBeanDiscovery
以及完整的 class 名稱為值來載入您 WebBeanDiscovery
的實做。例如:
org.jboss.webbeans.bootstrap.spi.WebBeanDiscovery=org.jboss.webbeans.integration.jbossas.WebBeanDiscoveryImpl
若 Web Bean RI 被使用在一個 servlet container 中的話,它會預期一個含有下列格式的 constructor:
public WebBeanDiscoveryImpl(ServletContext servletContext) {}
servlet 的 context 可被用來允許您 WebBeanDiscovery
的實做來與 container 進行互動。
Web Bean RI 也會委派 EJB3 bean discovery 至 container,因此它便無須掃描 EJB3 記號或剖析 ejb-jar.xml
。針對於應用程式中的各個 EJB 都應該能發現一個 EJBDescriptor:
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();
}
EjbDescriptor
本身已不解自明並且不需加以說明,它應會依照 EJB 規格中所定義地來回傳相關的 metadata。除了這兩個介面,還有個代表本地商業介面的 BusinessInterfaceDescriptor
(包含了使用來查詢某個 EJB instance 的 interface class 以及 jndi 名稱)。
Web Beans RI 可被指定來透過使用 org.jboss.webbeans.bootstrap.spi.EjbDiscovery
以及完整的 class 名稱為值來載入您 EjbDiscovery
的實做。例如:
org.jboss.webbeans.bootstrap.spi.EjbDiscovery=org.jboss.webbeans.integration.jbossas.EjbDiscoveryImpl
若 Web Bean RI 被使用在一個 servlet container 中的話,它會預期一個含有下列格式的 constructor:
public EjbDiscoveryImpl(ServletContext servletContext) {}
servlet 的 context 可被用來允許您 EjbDiscovery
的實做來與 container 進行互動。
Web Beans RI 會實做 JNDI 綁定並依照標準來進行搜尋,不過您可能在某些情況下會希望修改綁定和搜尋(比方說在一個 JNDI 無法使用的環境下)。若要如此,請實做 org.jboss.webbeans.spi.resources.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);
}
並告訴 RI 去使用它:
org.jboss.webbeans.resources.spi.NamingContext=com.acme.MyNamingContext
若 Web Bean RI 被使用在一個 servlet container 中的話,它會預期一個含有下列格式的 constructor:
public MyNamingContext(ServletContext servletContext) {}
servlet 的 context 可被用來允許您 NamingContext
的實做來與 container 進行互動。
Web Beans RI 需要在各個時段由 classpath 載入類別和資源。就預設值,它們會被由和使用來載入 RI 相同的 classloader 所載入,不過這對於某些環境來說可能不是不正確的。若是如此,您可實做 org.jboss.webbeans.spi.ResourceLoader
:
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);
}
並告訴 RI 去使用它:
org.jboss.webbeans.resources.spi.ResourceLoader=com.acme.ResourceLoader
若 Web Bean RI 被使用在一個 servlet container 中的話,它會預期一個含有下列格式的 constructor:
public MyResourceLoader(ServletContext servletContext) {}
servlet 的 context 可被用來允許您 ResourceLoader
的實做來與 container 進行互動。
Web Bean RI 對於 container 有些需求以便達到 API 實做之外的正確的功能。
若您要將 Web Bean RI 整合入某個支援多重應用程式建置的環境中,您就必須為各個 Web Bean 應用程式透過自動的方式,或是透過用戶配置來啟用 classloader 隔離。
若您要將 Web Bean 整合入一個 Servlet 環境中,您就必須為各個使用 Servlet 的 Web Bean 應用程式透過自動的方式,或是用戶配置來將 org.jboss.webbeans.servlet.WebBeansListener
註冊為一個 Servlet listener,
若您要將 Web Bean 整合入一個 EJB 環境中,您就必須針對於各個使用 enterprise bean 的 Web Bean 應用程式來為應用程式中的所有 EJB 透過自動的方式,或是透過用戶配置來將 org.jboss.webbeans.ejb.SessionBeanInterceptor
註冊為一個 EJB 攔截器。
webbeans-ri.jar
若您要將 Web Bean 整合入一個支援應用程式建置的環境中,您就必須將 webbeans-ri.jar
插入應用程式隔離的 classholder 中。它無法藉由共享的 classloader 來被載入。