SimpleRemoteStatelessSessionProxyFactoryBean 或者jee:remote-slsb>配置元素。当然了,无论是否使用Spring,远程调用语义都适用;在另一台电脑上另一个VM中一个对象的方法调用,有时候得使用上和失败处理上需要区别对待。


Spring的EJB客户端有着比非spring访问方式更多的优点。一般地,对于EJB客户端代码,本地或远程调用EJBs之间向后或向前转换,是有问题的。因为远程接口方法必须声明,它们要抛出RemoteException并且客户端代码必须处理这个,而本地接口方法不这样做。针对本地EJBs的客户端代码,需要移植到远程EJBs的,需要增加远程异常的处理,或者移除那些代码。使用spring的远程EJB代理,你可以在替换掉你的业务逻辑方法接口和实现的EJB代码中的任何RemoteException申明,你也可以有一个同样的远程接口,除了其抛出异常并依赖代理动态的处理两个接口,如果它们是相同的。即,客户端代码不必处理检查型RemoteException类。任何在EJB调用期间抛出的RemoteException将以非检查性RemoteAccessException类被重新抛出,其为RuntimeException的子类。目标业务,其将在本地EJB或远程EJB(甚至仅仅是一个POJO)实现中转化,而无需客户端代码知晓。当然了,这是可选的,你也可以在你的业务接口中声明RemoteExceptions。


22.2.4 Accessing EJB 2.x SLSBs versus EJB 3 SLSBs


EJB 2.x 会话beans 和EJB 3.x 会话beans的访问,借助Spring,很大程度上是透明的。Spring的EJB访问器,包括了<jee:local-slsb>和<jee:remote-slsb>元素,适应了运行期的实际组件。如果有home接口(EJB 2类型),就处理之,反之直接执行组件调用(EJB 3类型)。


注意:针对EJB 3会话beans,你也可以使用JndiObjectFactoryBean / <jee:jndi-lookup>,因为完全有用的组件引用暴露给JNDI查询。直接定义<jee:local-slsb> / <jee:remote-slsb>


22.3 使用Spring的EJB实现支持类


对于EJB 3 会话bean和消息驱动beans,Spring提供了方便的拦截器,其化解EJB组件(org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor)中的Spring的@Autowired注解。这个拦截器通过在EJB组件中使用@Interceptors或者在EJB的部署配置中使用interceptor-binding XML元素,可以得到应用。




@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class MyFacadeEJB implements MyFacadeLocal {

    // automatically injected with a matching Spring bean
    @Autowired
    private MyComponent myComp;

    // for business method, delegate to POJO service impl.
    public String myFacadeMethod(...) {
        return myComp.myMethod(...);
    }

    ...

}



SpringBeanAutowiringInterceptor 默认从ContextSingletonBeanFactoryLocator中获取目标beans,并有一个命名为beanRefContext.xml的bean定义的文件的上下文。默认地,单一上下文定义是可预料的,其通过类型获取而不是名字,然而,如果你需要在多个上下文定义中获取,需要一个指定的定位关键字。定位关键字(例如beanRefContext.xml中的上下文定义的名字)可以通过重写通用SpringBeanAutowiringInterceptor子类的getBeanFactoryLocatorKey方法指定。


作为可选地,考虑重写SpringBeanAutowiringInterceptor的getBeanFactory方法,从通用的持有者类中获取一个共享的ApplicationContext。