博主资料

留言 加为好友 收藏

用户名:  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日 09:05:52

EJB与Spring的集成(上)

     作为一个轻量级的容器,Spring通常被认为当作是EJB的替代方案。不可否认,在许多应用场合中,Spring以其卓越的性能与丰富的事务处理、ORM、JDBC存取等功能,确实可以取代EJB。不过,我们应当注意到,Spring本身并不排斥EJB,事实上,Spring还为在框架内部存取EJB、实现EJB的功能而提供了良好的支持。而且,如果利用Spring访问EJB所提供的服务,那么这些服务的具体实现可以在本地EJB、远程EJB,或者POJO之间进行透明地切换,而无需改动任何一行客户端的程序代码。

     在本文中,我们着重讨论一下Spring访问、实现EJB的机制,特别是对于无状态会话bean(SLSB)的支持。

 1.如何在Spring中访问EJB?
     在Java EE中,为了调用一个本地或者远程SLSB的方法,客户端必须首先通过JNDI查找获取一个(本地或者远程)EJB Home对象,而后通过这个 EJB Home对象的create()方法获取一个实际的(本地或者远程)EJB对象,从而调用此EJB对象的各种方法。
     为了避免底层代码的重复,许多EJB应用程序采用了Service Locator和Business Delegate设计模式,这比在客户端程序中使用很多JNDI查询要好很多,但其缺陷也是十分明显的,例如:
 *  依赖Service Locator和Business Delegate singleton的程序代码通常是难以测试的。
 *  若只使用Service Locator模式,而不使用Business Delegate,那么应用程序依旧必须调用一个EJB Home的craete()方法,并处理各种异常。因此,应用程序将与EJB的API与复杂编程模型紧密耦合在一起。
 *  使用Business Delegate模式通常将造成大量的重复代码,仅仅为了调用EJB的同一个方法,开发人员必须编写许多程序。

      而通过Spring,则可以创建和使用在Spring内部配置好的代理,这个代理将扮演业务delegate的角色,开发人员无需编写另外一个Service Locator和JNDI查询代码,也无需复制Business Delegate的方法调用,除非是在这些程序代码确实有其他有价值的内容。

     假设有一个需要使用本地EJB的web controller,我们将采用EJB的业务方法接口模式来实现,从而EJB的本地接口可以扩展一个非EJB的业务方法接口。我们将这个业务方法暂且称之为MyComponent,其定义类似于:


public interface MyComponent {
...
}

     使用业务方法接口模式的一个主要原因在于保证本地接口中的方法定义和接口实现bean的方法定义自动同步,另一原因是如果需要将该方法以POJO实现,那么这种转化将比较容易。当然,我们还需要实现本地home接口,并提供一个实现SessionBean和MyComponet业务方法接口的类。现在,为了将示例中的web controller与EJB实现挂钩,我们需要编写的唯一一段代码就是在这个controller中对外公开一个MyComponet对象的setter,示例如下:

private MyComponent myComponent;
public void setMyComponent(MyComponent myComponent) {
this.myComponent = myComponent;
}

      然后,便可以在controller中的任何一个业务方法中调用这个myComponet实例。假设需要在Spring容器之外获取该controller对象,我们可以在同一环境中配置一个LocalStatelessSessionProxyFactoryBean 实例作为EJB代理。这个代理的配置以及controller中myComponent属性的设置,均在Spring的配置文件定义,示例如下:

<bean id="myComponent"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
    <property name="jndiName" value="myComponent"/>
    <property name="businessInterface" value="com.ejbtest.MyComponent"/>
</bean>
<bean id="myController" class="com.ejbtest.myController">
    <property name="myComponent" ref="myComponent"/>
</bean>

     其中,通过myComponent的定义创建了一个EJB代理,而这个EJB将实现特定的业务方法接口。由于EJB的本地home在应用程序启动时就已经被缓存,所以这里只需要一个JNDI查询。每当这个EJB被调用时,EJB代理将调用本地EJB的classname()方法,并调用EJB提供的相应的业务方法。
 这种EJB存取机制极大地简化了应用程序代码,web层代码(抑或其他EJB客户端)将不再依赖EJB的使用。如果我们想将EJB替换为POJO或者其他测试stub,只要把配置文件中的myComponent定义改动一下即可,Java程序依旧保持不变。而且,我们也不必再编写任何JNDI查询代码,或者其他EJB的硬编码。


      实践表明,上述方法(包括对目标EJB的反射式调用)的运行开销是最小的。记住,我们并不想做任何针对EJB的细粒度调用,毕竟这涉及到Java应用服务器中EJB体系架构的成本开销。

       对于远程EJB的访问,本质上与访问本地EJB是相同的,除了需要SimpleRemoteStatelessSessionProxyFactoryBean类。当然,无论是否使用Spring,远程调用的基本语义是适用的。当访问另外一台电脑的虚拟机中某个对象的方法时,这种调用的具体用法和失败处理必须以不同于本地访问的方式处理。

(待续)

Tags: EJB   Spring  

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