Spring
对于
EJB
的支持
<o:p></o:p>
Spring
对
EJB
支持能够粗略的分成两类:访问和实现。
Spring
中的访问支持类使你能够容易的访问
EJB
资源。
Spring
提供了三种抽象类作为
EJB bean
类的基类,他们是:
<o:p></o:p>
l
AbstractStatelessSessionBean<o:p></o:p>
l
AbstractStatefulSessionBean<o:p></o:p>
l
AbstractMessageDrivenBean<o:p></o:p>
当使用
Spring
来构建
EJB
的时候,必须提供所有不同的接口和
home
类,在
JCF
介绍一节中已经做过介绍。但是,当实现
bean
类的时候,就需要从合适的
Spring
基类继承。
Spring
提供的基类允许
EJB
组件访问
Spring
的
ApplicationContext
,并且,这样允许这些组件访问
Spring
所管理的资源。
这有助于将业务逻辑从
EJB
实现中分离,写到
EJB
的
Spring
管理的
POJO
对象中。
<o:p></o:p>
Spring
提供的基类
AbstractEnterpriseBean
暴露了
beanFactoryLocator
属性来允许子类访问正在使用的实例
BeanFactoryLocator
。
AbstractStatelessSessionBean
类已经实现了
ejbCreate()
,
ejbActivate()
和
ejbPassivate()
方法,而类
AbstractStatefulSessionBean
并没有实现这些方法。
<o:p></o:p>
Spring
能够从
ApplicationContext
中装载所管理的资源,
Spring
中的
EJB
基类的主要特征就是能够访问
ApplicationContext
来装载资源。下面看看在系统的
SLSB
实例化的时候都做了些什么。
<o:p></o:p>
public
void
setSessionContext(SessionContext ctx) {
<o:p></o:p>
super
.setSessionContext(ctx);
<o:p></o:p>
setBeanFactoryLocator(ContextSingletonBeanFactoryLocator
<o:p></o:p>
.getInstance (
"classpath*:beanRefContext.xml"
));
<o:p></o:p>
setBeanFactoryLocatorKey(
"applicationContext-main"
);
<o:p></o:p>
}
<o:p></o:p>
|
SLSB
在第一次实例化的时候从
classpath
中加载
beanRefContext.xml
配置文件,生成一个
ContextSingletonBeanFactoryLocator
,再指明
BeanFactoryLocatorKey
为
applicationContext-main
。如下面所示:
<o:p></o:p>
<
beans
>
<o:p></o:p>
<
bean
name
=
"applicationContext-main"
<o:p></o:p>
class
=
"org.springframework.context.support.FileSystemXmlApplicationContext"
>
<o:p></o:p>
<
constructor-arg
>
<o:p></o:p>
<
list
>
<o:p></o:p>
<
value
>
etc/jcf/framework/config/applicationContext.xml
value > <o:p></o:p>
<
value
>
etc/jcf/framework/config/applicationContext-dao.xml
value > <o:p></o:p>
<
value
>
etc/jcf/framework/config/applicationContext-command.xml
value > <o:p></o:p>
<
value
>
etc/jcf/framework/config/applicationContext-jms.xml
value > <o:p></o:p>
<
value
>
etc/jcf/framework/config/applicationContext-service.xml
value > <o:p></o:p>
value
>
etc/jcf/framework/config/applicationContext-processor.xml
value > <o:p></o:p>
list > <o:p></o:p>
constructor-arg > <o:p></o:p>
bean > <o:p></o:p>
beans > <o:p></o:p>
|
beanRefContext.xml<o:p></o:p>
<o:p> </o:p>
在
beanRefContext.xml
文件中指明了
Spring
所用到的配置文件在文件系统中的位置。
Spring
能够从
ApplicationContext
中装载所管理的资源的功能不是基类本身提供的,而是被委托给
BeanFactoryLocator
接口的实现,如下所示:
<o:p></o:p>
abstract
class
AbstractEnterpriseBean
implements
EnterpriseBean {
protected BeanFactory getBeanFactory() { <o:p></o:p>
return
this
.
beanFactoryReference
.getFactory ();
<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
|
BeanFactoryLocator
接口
<o:p></o:p>
<o:p> </o:p>
BeanFactoryLocator
并不直接返回
BeanFactory
实例;而是返回一个
BeanFactoryReference
。
BeanFactoryReference
是一个轻量级
BeanFactory
或
ApplicationContext
的包装器,这个包装器允许使用
BeanFactory
的资源平滑地释放对
BeanFactory
的引用。缺省情况下,所有
EJB
基类使用了
BeanFactoryLocator
的
实现。本质上来说,这个类在一个给定
JNDI
地点上查找一个逗号分隔的配置文件列表,并且使用这些配置文件来创建
ClassPathXmlApplicationContext
的实例。三个基本
EJB
类都通过
AbstractEnterpriseBean
类表现出属性
beanFactoryLocator
,通过设置这个属性,就能够提供你自己对于
BeanFactoryLocator
的不同实现。然而,如果你这样做了,那么,
bean
的每一个实例都有它自己的
ContextJndiBeanFactoryLocator
实例,同样,每个
ContextJndiBeanFactoryLocator
的实例都有它自己的
ClassPathXmlApplicationContext
实例。
<o:p></o:p>
虽然为你的
EJB
实例创建的所有
ApplicationContext
实例都用同样的方式配置的,但是,所配置的
bean
是不一样的。如果你的应用程序服务器创建
100EJB
个实例,那么,也创建了
100
个
ContextJndiBeanFactoryLocator
的实例,以及
100
个
ClassPathXmlApplicationContext
。如果应用程序不希望发生这种情况,那么
Spring
提供
SingletonBeanFactoryLocator
和
ContextSingletonBeanFactoryLocator
类来分别装载
BeanFactory
和
ApplicationContext
的单件实例。