Spring不僅是EJB替代品,更提供無縫EJB集成能力。通過代理模式簡化JNDI查找、Home創建、業務委托樣板代碼,實現本地/遠程EJB與POJO透明切換。
業務接口(非EJB專用):
public interface MyComponent { void doBusiness(); }
EJB實現:
public class MyComponentEJB implements SessionBean, MyComponent {
public void doBusiness() { ... }
// ejbCreate/setSessionContext等生命周期方法
}
Spring配置:
<bean id="myComponent" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/MyComponent" />
<property name="businessInterface" value="com.mycom.MyComponent" />
</bean>
<bean id="myController" class="com.mycom.MyController">
<property name="myComponent" ref="myComponent" />
</bean>
控制器僅依賴MyComponent接口,完全解耦EJB。
使用SimpleRemoteStatelessSessionProxyFactoryBean,額外優勢:
RemoteExceptionRemoteException轉為未檢查異常RemoteAccessException默認啟動時查找並緩存Home。若EJB容器啟動較晚,設置lazy-init="true"延遲到首次使用:
<bean id="myComponent" class="..." lazy-init="true"> ... </bean>
提倡「業務邏輯放POJO,EJB只負責事務/遠程」:
public class MyComponentEJB extends AbstractStatelessSessionBean implements MyComponent {
private MyComponent pojo;
protected void onEjbCreate() throws CreateException {
pojo = (MyComponent) getBeanFactory().getBean("myComponentPojo");
}
public void doBusiness() { pojo.doBusiness(); }
}
ContextJndiBeanFactoryLocator:從java:comp/env/ejb/BeanFactoryPath加載setSessionContext使用ContextSingletonBeanFactoryLocatorpublic void ejbPassivate() { unloadBeanFactory(); }
public void ejbActivate() { loadBeanFactory(); }
因ApplicationContext不可序列化,需手動卸載/重載。
LocalStatelessSessionProxyFactoryBean隔離客戶端