SeamFramework.orgCommunity Documentation
目前,Web Bean的参考实现只能运行在JBoss AS5中;将参考实现整合到其他EE环境中(例如像Glassfish的其他的应用服务器)以及一个Servlet容器(像Tomcat)中或者一个内嵌的EJB3.1实现中相当容易。在附录中我们将简要的讨论所需的步骤。
Web Bean可以在SE环境中运行,但是你需要做更多的工作,添加你自己的上下文和生命周期。Web Bean参考实现目前没有暴露生命周期扩展点,所以你不得不直接编写Web Bean参考实现的类。
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.
所有的SPI接口都支持装饰器模式,并且提供一个 Forwarding
类。
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规范中已经描述了,这里就不再重复)
Web Bean参考实现也将EJB3 Bean的发现委托给容器,以便它不用再扫描EJB3注释和解析 ejb-jar.xml
文件。对于应用中的每个EJB都应发现一个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();
}
EjbDescriptor
具有相当的自解释性,应该返回EJB规范中定义的相关元数据。除了这两个接口,还有一个表示本地业务接口的 BusinessInterfaceDescriptor
(封装了接口类和用于查询EJB实例的jndi名字)
The resolution of @EJB
and @Resource
is delegated to the container. You must provide an implementation of org.jboss.webbeans.ejb.spi.EjbServices
which provides these operations. Web Beans passes in the javax.inject.manager.InjectionPoint
the resolution is for, as well as the NamingContext
in use for each resolution request.
Just as resolution of @EJB
is delegated to the container, so is resolution of @PersistenceContext
.
OPEN ISSUE: Web Beans also requires the container to provide a list of entities in the deployment, so that they aren't discovered as simple beans.
Web Bean RI必须将JTA活动委托给容器。SPI提供者提供一些钩子(hooks)结合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();
}
枚举 Status
对实现者来说是一个很方便的工具,可以追踪在事务成功或者失败或者无论事务成功还是失败的情况下,是否应该将一个同步通知给观察者。
任何 javax.transaction.Synchronization
实现必须传递给 registerSynchronization()
方法,SPI实现应该立刻将同步注册到EJB使用的JTA事务管理器。
为了更容易的决定对于请求线程来说一个事务在当前是否是活动的,我们可以使用isTransactionActive()
方法。SPI实现应该查询EJB使用的同一个JTA事务管理器。
Web Bean期望应用服务器或者其他容器能够提供每个应用上下文的存储。org.jboss.webbeans.context.api.BeanStore
应该被实现以便提供一个应用范围的存储。你也许会发现 org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore
非常有用。
org.jboss.webbeans.bootstrap.api.Bootstrap
接口定义了Web Bean的自举机制。为了启动Web Beans,你必须获得一个org.jboss.webbeans.bootstrap.WebBeansBootstrap
实例(它实现了Boostrap
) ,告诉它使用的SPI,然后请求容器启动。
The bootstrap is split into phases, bootstrap initialization and boot and shutdown. Initialization will create a manager, and add the standard (specification defined) contexts. Bootstrap will discover EJBs, classes and XML; add beans defined using annotations; add beans defined using XML; and validate all beans.
The bootstrap supports multiple environments. Different environments require different services to be present (for example servlet doesn't require transaction, EJB or JPA services). By default an EE environment is assumed, but you can adjust the environment by calling bootstrap.setEnvironment()
.
To initialize the bootstrap you call Bootstrap.initialize()
. Before calling initialize()
, you must register any services required by your environment. You can do this by calling bootstrap.getServices().add(JpaServices.class, new MyJpaServices())
. You must also provide the application context bean store.
调用initialize()
后,我们能够通过Bootstrap.getManager()
来获得管理器
。
To boot the container you call Bootstrap.boot()
.
要关闭容器,你需要调用 Bootstrap.shutdown()
。这将让容器执行一些必要的清洁工作。
Web Beans 参考实现实现了JNDI 的绑定和根据标准来查询,然而你可能想要改变这些绑定和查询(例如在一个没有JNDI的环境中)。你可以通过实现 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);
}
Web Beans参考实现需要在不同时间从类路径上加载类和资源。默认情况下,它们使用加载参考实现的类加载器加载,但是这在一些环境中可能是不适合的。如果出现这种情况的话,你可以实现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);
}
为了接口实现之外的正确的功能,Web Beans参考实现对容器有大量的要求。
如果你将一个Web Bean参考实现整合到一个支持多应用部署的环境中,你需要以用户配置或者自动化方式为每个Web Bean应用激活类加载器隔离。
如果你将Web Bean整合到一个Servlet环境中,对每个使用Servlet的 Web Bean应用,你需要以用户配置或者自动化形式将 org.jboss.webbeans.servlet.WebBeansListener
注册为一个Servlet监听器。
如果你将Web Bean整合到一个JSF环境中,对每个使用JSF的 Web Bean应用,你需要以用户配置或者自动化形式将 org.jboss.webbeans.servlet.ConversationPropagationFilter
注册为一个Servlet监听器。这个过滤器可以安全地向所有Servlet部署注册。
如果你将Web Beans整合到EJB环境中,对每个使用企业级Bean的Web Bean应用,你需要以用户配置或者自动化形式将 org.jboss.webbeans.ejb.SessionBeanInterceptor
注册为应用中所有EJB的EJB拦截器。
你必须为所有的EJB在栈中将SessionBeanInterceptor
注册为一个最内部的拦截器。
webbeans-core.jar
If you are integrating the Web Beans into an environment that supports deployment of applications, you must insert the webbeans-core.jar
into the applications isolated classloader. It cannot be loaded from a shared classloader.