在基于Ejb的开发中,一般有两种通信方式:一、同步方式;二、异步方式。同步方式就是通过实现sessionBeans,实现通信,而异步通信是基于JMS的message-driven beans。这两种组件类型都是由Ejb容器来进行管理的。
(一般应用中,需要开发人员进行开发的SessionBean、MDB以及JPA映射的实体)
今天我们首先来研究SessionBean。
PS:同步的概念大家并不陌生,这里同步就是指客户端对服务端的调用时同步进行的。客户端发出请求后并没有完,还会等待服务端做出相应的反应。
SessionBean也称为会话Bean,它分为两种类型:无状态会话Bean和有状态会话Bean。即:
@stateless
@stateful
无状态回话Bean
无状态会话Bean,就想名字一样,它并不关心会话状态,这就意味着一次任务会在一次单一调用中结束。在实际项目应用开发中,无状态会话Bean也是最常用的。
所谓的无状态回话Bean(Stateless Session Bean),无状态sessionbean实例能够放在池里,而且可能被多个客户端所共享。当一个客户端调用一个无状态sessionbean时,容器可能会为客户端在池中创建一个新的实例或者从实例池中拿出来一个。实例用完之后会返还到池中。这就意味着,池中的少量bean实例能够为大量的客户提供端服务。如下图:
(无状态回话Bean,调用完成后,马上返回池中,准备再次被调用)
有状态会话Bean
有状态会话Bean会保存会话状态。它与无状态会话Bean很相像,唯一一点不同就是容器管理它们的生命周期的方式不同。在有状态会话Bean调用中,容器要确保同一客户端前后几次调用的是同一个有状态会话Bean。容器确保bean实例与客户端的一对一的调用关系,所以在开发者看来,它们是好像是自动的。
但是,这种一对一的调用时很耗费资源的。客户端session打开的时候,bean实例不能返回池中供其他的客户端调用,它会一直驻留在内存中,等待同一客户端的下一次调用。结果,当前大量的客户端访问导致有状态会话Bean占具大量的内存。
每一个有状态会话Bean实例都保存了一个客户端的状态信息,这个实例会一直存在,直到客户端删除它,或者session过期。
有状态会话Bean的适用情况很多,像多步操作、基于工作流程的业务逻辑等。
(有状态会话Bean,每个实例都会一直保存了一个客户端的状态信息)
业务逻辑接口类型
无论是有状态会话Bean还是无状态会话Bean,他们都有两种类型,如图:
@Local
@Remote
(local与remote的存在关系)
本地接口
如上图,本地接口调用要求,客户端与当前bean部署在同一虚拟机(JVM)中,也就是在同一台服务器(如Jboss)中。
远程接口
如上图,远程接口就要求,客户端与当前bean部署在不同的虚拟机(JVM)中,如Tomcat调用jboss属于远程调用,或者JbossA中的应用调用JbossB中的应用也属于远程调用。
至于本地接口与远程接口的区别,请看这里:解读Ejb中Local与Remote项目
关于本地接口与远程接口的使用过程中,注意点问题,请看这里:JBoss5中Local与Remote不能同时存在的问题
开发期间,我们可能在同一台机器上启多个Jboss服务器实例,请看这里:通过Jboss启动多个实例解决服务器资源问题
总结
在分布式项目开发中,由于大部分业务一般都是不要求保存客户端状态的,所以我们会大量使用无状态SessionBean,然而在遇到多步操作、基于工作流程的业务逻辑时,我们就要考虑使用有状态的SessionBean,例如像购物车的经典实例,我们就需要使用有状态的SessionBean。
本文简要介绍了分布式开发中,同步方式的有状态会话Bean与无状态会话Bean这两种方式的基本概念,下篇文章同步方式中的其他内容。