SeamFramework.orgCommunity Documentation
Currently Web Beans only runs in JBoss AS 5; integrating the RI into other EE environments (for example another application server like Glassfish), into a servlet container (like Tomcat), or with an Embedded EJB3.1 implementation is fairly easy. In this Appendix we will briefly discuss the steps needed.
The Web Beans SPI is located in the webbeans-spi
module, and packaged as webbeans-spi.jar
. Some SPIs are optional, if you need to override the default behavior, others are required.
All interfaces in the SPI support the decorator pattern and provide a Forwarding
class located in the helpers
sub package. Additional, commonly used, utility classes, and standard implementations are also located in the helpers
sub package.
/**
* Gets list of all classes in classpath archives with META-INF/beans.xml (or
* for WARs WEB-INF/beans.xml) files
*
* @return An iterable over the classes
*/
public Iterable<Class<?>> discoverWebBeanClasses();
/**
* Gets a list of all deployment descriptors in the app classpath
*
* @return An iterable over the beans.xml files
*/
public Iterable<URL> discoverWebBeansXml();
The discovery of Web Bean classes and beans.xml
files is self-explanatory (the algorithm is described in Section 11.1 of the JSR-299 specification, and isn't repeated here).
Web Beans will run without an EJB container; in this case you don't need to implement the EJB SPI.
Web Beans also delegates EJB3 bean discovery to the container so that it doesn't have to scan for EJB3 annotations or parse ejb-jar.xml
. For each EJB in the application an EJBDescriptor should be discovered:
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
(for injection into simple beans), the resolution of local EJBs (for backing session beans) and remote EJBs (for injection as a Java EE resource) is delegated to the container. You must provide an implementation of org.jboss.webbeans.ejb.spi.EjbServices
which provides these operations. For resolving the @EJB
injection point, Web Beans will provide the InjectionPoint
; for resolving local EJBs, the EjbDescriptor
will be provided, and for remote EJBs the jndiName
, mappedName
, or ejbLink
will be provided.
When resolving local EJBs (used to back session beans) a wrapper (SessionObjectReference
) around the EJB reference is returned. This wrapper allows Web Beans to request a reference that implements the given business interface, and, in the case of SFSBs, request the removal of the EJB from the container.
Just as EJB resolution is delegated to the container, resolution of @PersistenceContext
for injection into simple beans (with the InjectionPoint
provided), and resolution of persistence contexts and persistence units (with the unitName
provided) for injection as a Java EE resource is delegated to the container.
To allow JPA integration, the JpaServices
interface should be implemented.
Web Beans also needs to know what entities are in a deployment (so that they aren't managed by Web Beans). An implementation that detects entities through @Entity
and orm.xml
is provided by default. If you want to provide support for a entities defined by a JPA provider (such as Hibernate's .hbm.xml
you can wrap or replace the default implementation.
EntityDiscovery delegate = bootstrap.getServices().get(EntityDiscovery.class);
Web Beans 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();
}
枚举 Status
对实现者来说是一个很方便的工具,可以追踪在事务成功或者失败或者无论事务成功还是失败的情况下,是否应该将一个同步通知给观察者。
任何 javax.transaction.Synchronization
实现必须传递给 registerSynchronization()
方法,SPI实现应该立刻将同步注册到EJB使用的JTA事务管理器。
为了更容易的决定对于请求线程来说一个事务在当前是否是活动的,我们可以使用isTransactionActive()
方法。SPI实现应该查询EJB使用的同一个JTA事务管理器。
A number of JMS operations are not container specific, and so should be provided via the SPI JmsServices
. JMS does not specify how to obtain a ConnectionFactory
so the SPI provides a method which should be used to look up a factory. Web Beans also delegates Destination
lookup to the container via the SPI.
The resolution of @Resource
(for injection into simple beans) and the resolution of resources (for injection as a Java EE resource) is delegated to the container. You must provide an implementation of ResourceServices
which provides these operations. For resolving the @Resource
injection, Web Beans will provide the InjectionPoint
; and for Java EE resources, the jndiName
or mappedName
will be provided.
The resolution of web service references (for injection as a Java EE resource) is delegated to the container. You must provide an implementation of WebServices
whichprovides this operation. For resolving the Java EE resource, the jndiName
or mappedName
will be provided.
Web Beans uses a map like structure to store bean instances - org.jboss.webbeans.context.api.BeanStore
. You may find org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore
useful.
Web Beans expects the Application Server or other container to provide the storage for each application's context. The org.jboss.webbeans.context.api.BeanStore
should be implemented to provide an application scoped storage.
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. An environment is defined by an implementation of the Environment
interface. A number of standard envrionments are built in as the enumeration 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()
.
Web Beans uses a generic-typed service registry to allow services to be registered. All services implement the Service
interface. The service registry allows services to be added and retrieved.
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()
.
To shutdown the container you call Bootstrap.shutdown()
or webBeansManager.shutdown()
. This allows the container to perform any cleanup operations needed.
Web Beans delegates all JNDI operations to the container through the SPI.
A number of the SPI interface require JNDI lookup, and the class AbstractResourceServices
provides JNDI/Java EE spec compliant lookup methods.
Web Beans needs to load classes and resources from the classpath at various times. By default, they are loaded from the Thread Context ClassLoader if available, if not the same classloader that was used to load Web Beans, however this may not be correct for some environments. If this is case, you can implement 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监听器。
If you are integrating the Web Beans into a JSF environment you must register org.jboss.webbeans.jsf.WebBeansPhaseListener
as a phase listener, and org.jboss.webbeans.el.WebBeansELREsolver
as an EL resolver, either automatically, or through user configuration, for each Web Beans application which uses JSF.
如果你将Web Bean整合到一个JSF环境中,对每个使用JSF的 Web Bean应用,你需要以用户配置或者自动化形式将 org.jboss.webbeans.servlet.ConversationPropagationFilter
注册为一个Servlet监听器。这个过滤器可以安全地向所有Servlet部署注册。
Web Beans only supports JSF 1.2 and above.
如果你将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.
You should bind a Reference
to the Manager ObjectFactory
into JNDI at java:app/Manager
. The type should be javax.inject.manager.Manager
and the factory class is org.jboss.webbeans.resources.ManagerObjectFactory