博主资料

留言 加为好友 收藏

用户名:  moonstone2007
来自:  浙江 杭州

文章搜索

文章列表

最近访问的人:

满庭芳
2008-10-04 13:52:46
常州赛维思环境试..
2008-09-30 16:17:41
sdgjhgekjuiwe
2008-06-14 15:34:54
泌尿系结石
2008-06-03 14:15:13
兵,器
2008-06-03 10:04:56
电子商务研究(B2C)
2008-06-02 15:12:38
直流电源,直流稳压..
2008-06-02 11:17:38
玩ERP
2008-06-02 08:32:57
李雪
2008-05-14 15:29:59
三笑数码科技--电..
2008-05-14 15:17:37

日志文章

2007年04月30日 15:50:29

EJB与Spring的集成(下)

    Spring在EJB客户端支持方面,比非Spring方案具有更多优势。通常,EJB客户端在调用 本地或远程EJB时,很难做自由的前后切换。 这是因为远程接口方法必须抛出RemoteException,并且客户端程序必须处理此异常,但对于本地接口方法的调用则不需要这么做。若将处理本地EJB的客户端程序用来处理远程EJB,那么必须作出修改以增加对远程异常情况的有效处理,同样,若将处理远程EJB的客户端程序用来处理本地EJB,也需要做很多无谓的工作来处理远程异常,或者将异常处理的程序代码删除。不过,当使用Spring远程EJB代理时,开发人员不必在业务逻辑方法接口和具体的EJB实现代码中声明抛出任何RemoteException,并且将有一个统一的远程接口(这个接口抛出RemoteException),并通过这个代理动态地分析客户端调用的是远程EJB还是本地EJB。 也即,客户端程序不需要再处理RemoteException,在调用EJB过程中抛出的任何RemoteException均将被重新以RemoteAccessException类的形式抛出。于是,应用程序可以在本地EJB和远程EJB(甚至是POJO)间任意切换调用,而客户端代码无需关心这些后台的操作。当然,这个解决方案是可选的,用户可以根据自己的意愿在业务接口中声明抛出RemoteExceptions。

2.如何利用Spring实现EJB

      Spring还提供了若干易于使用的类,来帮助开发人员实现EJB。Spring鼓励开发人员将业务逻辑以POJO的形式实现,而将EJB的处理重点放在事务分界与远程调用。
       无论是无状态的会话bean,还是有状态的会话bean,抑或消息驱动的bean,其实现均需分别继承AbstractStatelessSessionBean, AbstractStatefulSessionBean, 和
AbstractMessageDrivenBean/AbstractJmsMessageDrivenBean。
      考虑一个无状态的会话bean的例子。业务接口定义如下:

public interface MyComponent {
   public void myMethod(...);
   ...
}
      我们用一个POJO实现该接口:

public class MyComponentImpl implements MyComponent {
 public String myMethod(...) {
 ...
 }
 ...
}


 最后,定义无状态的会话bean:
 
public class MyComponentEJB extends AbstractStatelessSessionBean
implements MyComponent {

MyComponent myComp;

/**
* 从BeanFactory或者ApplicationContext获取POJO对象
* @参见 org.springframework.ejb.support.AbstractStatelessSessionBean的onEjbCreate()方法
*/
protected void onEjbCreate() throws CreateException {
myComp = (MyComponent) getBeanFactory().getBean(
ServicesConstants.CONTEXT_MYCOMP_ID);
}

// 具体的业务方法,以POJO实现
public String myMethod(...) {
return myComp.myMethod(...);
}
...
}

 AbstractStatelessSessionBean缺省地创建并装载一个Spring IoC容器,这个容器对EJB也是有用处的,例如获取POJO服务对象。容器的装载过程由 BeanFactoryLocator的一个子类完成,缺省情况下使用ContextJndiBeanFactoryLocator来实现。 ContextJndiBeanFactoryLocator从一个资源文件创建ApplicationContext,资源文件的位置由JNDI环境变量指定,例如java:comp/env/ejb/BeanFactoryPath。如果需要更改BeanFactory/ApplicationContext装载策略,那么缺省的BeanFactoryLocator实现可以通过调用setBeanFactoryLocator()方法来重载,这个方法可以在setSessionContext()或者EJB的构造函数中进行调用。
 有状态的会话bean在其生命周期中存在休眠与激活的过程,若此有状态的会话bean使用了一个非序列化的容器实例,由于该bean无法被EJB容器保存,因此它必须从 ejbPassivate()和ejbActivate()分别手工地调用unloadBeanFactory()和loadBeanFactory()方法。为了使用EJB,ContextJndiBeanFactoryLocator类需要装载一个ApplicationContext,这足以一般情况的需要。不过,若ApplicationContext装载很多bean,或者这些bean的初始化可能占用大量时间或内存资源的话,例如初始化Hibernate的一个SessionFactory对象,这个解决方案就存在较大的问题,因为每一个EJB都将会有自己的一个copy。在此情况下,开发人员可以考虑重载缺省的ContextJndiBeanFactoryLocator,并使用BeanFactoryLocator的另一个变体,例如ContextSingletonBeanFactoryLocator类,这样便可以在多个EJB或客户端之间共享同一个容器。示例如下:

/**
* 重载缺省的BeanFactoryLocator实现
* @参见javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
*/
public void setSessionContext(SessionContext sessionContext) {
super.setSessionContext(sessionContext);
setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
setBeanFactoryLocatorKey(ServicesConstants.PRIMARY_CONTEXT_ID);
}

 而后,创建一个bean定义文件,例如beanRefContext.xml,这个文件将定义EJB可能会用到的所有bean工厂。一般情况下,这个文件将只包含一个bean的定义,例如:

<beans>
<bean id="businessBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="businessApplicationContext.xml" />
</bean>
</beans>

 其中 businessApplicationContext.xml文件包含了全部业务POJO对象的定义。ServicesConstants.PRIMARY_CONTEXT_ID则可以定义如下:

public static final String ServicesConstants.PRIMARY_CONTEXT_ID = "businessBeanFactory";


3.EJB与Spring究竟在何时进行集成? 

     尽管Spring和EJB的目标都是为松散耦合的POJO提供企业级服务,但现在很多人都认为Spring+Hibernate的方案,可以充分替代EJB,尤其EJB复杂的编程模型总是令人望而生畏,EJB的部署、运行效率亦总为人诟病。不过,EJB尤其是EJB 3.0在复杂信息系统构建方面,依旧有着Spring目前不能超越的特性。使用EJB 3.0的时候,基于标准的方法、注释的使用、以及与应用程序服务器的紧密集成,实现了厂商无关性,并提高开发效率。尤其是,EJB 3.0在面向事务处理的、尤其是异步通讯环境下的企业级应用方面,比Spring更具备优势。在处理fail-over、load balancing、distributed caching和state duplication、clustering等方面,开发人员在EJB 3.0的环境中不必关心这些问题(当然,在部署时需要考虑)。而在Spring中,需要使用声明式事务服务来管理Hibernate事务,开发人员必须在XML配置文件中显式地配置Spring TransactionManager和Hibernate SessionFactory对象。Spring应用程序开发者必须显式地管理跨多个HTTP请求的事务。此外,要在Spring应用程序中使用群集服务也没有简单的途径。


       EJB与Spring本质上是相互竞争且相互学习的技术,很难说二者的集成是否能够充分彰显二者的优点,弥补彼此的缺陷。

 

Tags: EJB   Spring  

类别: 软件开发技术 |  评论(0) |  浏览(2489) |  收藏
发表评论
看不清楚,换一张