EJB一个最大的缺点就是要想脱离EJB容器而单独测试EJB组件非常困难。通过Spring可以解决这个问题,将业务逻辑写在POJO中,然后,通过EJB委托给POJO来执行操作。在Spring中,由于不必将如何定位和创建POJO的实现的任何逻辑嵌入到EJB中,这种实现就是非常简单,和灵活的。下面是一个继承于AbstractStatelessSessionBean的无状态会话Bean的基类,系统中的每个SLSB都继承于此类。所有的请求都通过这个SLSB来转发给POJO。因为每次初始化的内容都不一样,所以将初始化放到了SLSB的每个继承类中。<o:p></o:p>
<o:p> </o:p>
public abstract class SessionFacade extends AbstractStatelessSessionBean {<o:p></o:p>
/**<o:p></o:p>
* 如果子类需要进行全局的初始化工作,那么应该Override这个方法。<o:p></o:p>
*/<o:p></o:p>
public abstract void init();<o:p></o:p>
protected void onEjbCreate() throws CreateException {<o:p></o:p>
synchronized (initLock) {<o:p></o:p>
if (globalInit)<o:p></o:p>
return;<o:p></o:p>
else {<o:p></o:p>
init();<o:p></o:p>
globalInit = true;<o:p></o:p>
……<o:p></o:p>
|
SLSB的基类<o:p></o:p>
<o:p> </o:p>
public class JCFServerFacadeBean extends SessionFacade<o:p></o:p>
{<o:p></o:p>
public void init()<o:p></o:p>
{<o:p></o:p>
ContextServiceLocator.getInstance().setContext(getBeanFactory());<o:p></o:p>
boolean bret = ServiceLocator.getInstance().init("etc/jcf/framework/config/ServiceConfig.xml"); <o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
|
SLSB的继承类<o:p></o:p>
<o:p> </o:p>
如上面的代码所示,由于在SLSB的初始化方法setSessionContext中实例化Spring的ApplicationContext,Spring的配置文件在类路径中的beanRefContext.xml文件标识,所以在SLSB的继承类中,调用getBeanFactory方法可以得到Spring的ApplicationContext,并赋予给ContextServiceLocator,方便以后的调用。<o:p></o:p>
无状态会话bean是用Spring最容易构建的EJB;这是因为无论在何种情况下,它都不需要特殊的处理,并且类AbstractStatelessSessionBean实现了所有ejbXXX()方法。<o:p></o:p>
因为真正的业务逻辑是写在POJO中的,SLSB的作用相当于SessionFacade模式中的Façade,在Delegate模式中的Delegate的请求都是通过Façade传到了后面的Processor,所以在系统中只需要一个或者是少量的几个SLSB就可以满足需求。甚至可以绕过SLSB通过POJODelegate访问后面的Processor,这给平时的开发带来的极大的灵活性。<o:p></o:p>
对于异步的消息驱动Bean(MDB),Spring同样作出了支持。类似SLSB,MDB只要继承AbstractMessageDrivenBean,并实现MessageListener接口即可。同样在setMessageDrivenContext方法中初始化Spring的ApplicationContext,所有从Delegate的请求都通过execute方法传给Processor。在MDB继承类中的OnMessage方法就可以访问到Spring的ApplicationContext了。在此就不再罗嗦了。<o:p></o:p>