SSH深度历险(三) EJB Session Bean有状态和无状态的差别与联系
刚開始对两种sessionbean存在误解。觉得有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用。而觉得无状态是每次调用实例化一次,不保留用户信息。细致分析并用实践检验后,会发现,事实恰好相反:有状态和无状态会话bean的本质差别是它们的生命期。
首先解释一个以下要用到的概念--用户:sessionbean 的用户实际上就是直接调用ejb的类的实例,甚至是这个实例的某个方法。同一个类的不同实例对于session bean来说是不同的用户。
实例解析
有状态的StatefulEjb接口
<span style="font-size:18px;"><span style="font-size:18px;">package com.bjsxt.ejb;
public interface StatefulEjb {
public void compute(int i);
public int getResult();
}
</span></span>
StatefulEjb的实现
<span style="font-size:18px;"><span style="font-size:18px;">package com.bjsxt.ejb; import javax.ejb.Remote;
import javax.ejb.Stateful;
@Stateful
@Remote public class StatefulEjbBean implements StatefulEjb { private int state;
public void compute(int i) {
state = state +1; } public int getResult() { return state;
} }
</span></span>
无状态接口StatelessEjb
<span style="font-size:18px;"><span style="font-size:18px;">package com.bjsxt.ejb;
public interface StatelessEjb {
public void compute(int i);
public int getResult();
}
</span></span>
无状态接口StatelessEjb实现
<span style="font-size:18px;"><span style="font-size:18px;">package com.bjsxt.ejb; import javax.ejb.Remote;
import javax.ejb.Stateless; @Stateless
@Remote
public class StatelessEjbBean implements StatelessEjb { private int state;
public void compute(int i) {
state = state +1; } public int getResult() { return state;
} }
</span></span>
client配置jndi
<span style="font-size:18px;"><span style="font-size:18px;">java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost</span></span>
有状态的client编写
<span style="font-size:18px;"><span style="font-size:18px;">package com.bjsxt.ejb;
import javax.naming.InitialContext;
public class StatefulEjbClient {
public static void main(String[] args) throws Exception{
InitialContext context = new InitialContext();
//第一次回話
StatefulEjb ejb1 =(StatefulEjb)context.lookup("StatefulEjbBean/remote");
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
//第二次会话
StatefulEjb ejb2 = (StatefulEjb)context.lookup("StatefulEjbBean/remote");
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
}
}
</span></span>
结果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlzaGVoZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
无状态client编写
<span style="font-size:18px;"><span style="font-size:18px;">package com.bjsxt.ejb;
import javax.naming.InitialContext;
public class StatelessEjbClient {
public static void main(String[] args) throws Exception{
InitialContext context = new InitialContext();
//第一次回話
StatelessEjb ejb1 =(StatelessEjb)context.lookup("StatelessEjbBean/remote");
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
//第二次会话
StatelessEjb ejb2 = (StatelessEjb)context.lookup("StatelessEjbBean/remote");
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
System.out.println("ejb1 == ejb2 ?:"+(ejb1 == ejb2));
}
}
</span></span>
结果
有状态会话bean:每一个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”。一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每一个用户最初都会得到一个初始的bean。
无状态会话bean :bean一旦实例化就被加进会话池中。各个用户都能够共用。
即使用户已经消亡,bean的生命期也不一定结束,它可能依旧存在于会话池中,供其它用户调用。因为没有特定的用户。那么也就不能保持某一用户的状态。所以叫无状态bean。但无状态会话bean并不是没有状态。假设它有自己的属性(变量),那么这些变量就会受到全部调用它的用户的影响。这是在实际应用中必须注意的。
差别的根本原因
对于有状态会话Bean来说,仅仅要有client发送对有状态会话Bean的訪问。server都会创建一个会话Bean实例与该client相应,这样这个实例与这个client就是一一相应的。
假设client在Bean实例中保存了信息,之后还能够使用。
对于无状态会话Bean来说,server端会维持一个实例池,创建好若干个实例对象供client调用。当从client发送创建会话Bean的请求时,并不一定会真的创建 EJB,多数情况下是从实例池中得到一个实例。用完之后又一次放回实例池。
假设下次再訪问,再从实例池中取出一个实例使用,并不一定是上次的实例。即使两次訪问使用的是同一个实例。在两次訪问之间也有可能有其它的client訪问了该实例。所以,并不能保证在多次訪问之间的信息会被保存。所以,无状态会话Bean 不会专门保存client的信息。
各自的优缺点
由于有状态会话Bean须要保存特定client的信息,一个client相应一个实例,既是在当时client有连接没有訪问的情况下,也要为这个client保留这个实例。这样随着client数量的添加,server端须要创建的实例的数量也在添加,添加到一定程度对server的性能就会有一定的影响。为了不正确server的性能产生影响,通常server会进行一些优化。
当client的数量超过某个值之后。就不创建新的实例。
尽管不创建新的实例。还是须要对用户响应。这时候就採用共享实例的方式。会查看哪个实例尽管处于连接状态,可是没有訪问。然后把这个实例的状态保存起来,使用这个实例为新的请求服务。对于原来的client来说,称为挂起。
假设原来的client又发送请求了,会又一次查找一个空暇的实例而且把已经保存好的状态恢复回来,这个过程称为激活。所以在有状态会话Bean的訪问过程。常常会发生查找实例,激活挂起等操作,所以效率比較低。
而发送对无状态会话Bean的请求的时候,能够随便取一个空暇的实例为client服务,所以效率比較高。
有状态会话Bean的优点是,能够保存client的状态,所以client在兴许訪问的时候就能够少传递一些參数。而无状态会话Bean须要传递方法运行过程中须要的全部參数。
怎样选择
依据上面分析的有状态会话Bean和无状态会话Bean的优缺点。假设要频繁的訪问。而且多次訪问之间会共享一些信息,这时候应该使用有状态会话Bean。对于不常常使用的功能,能够使用无状态会话Bean。无状态会话Bean的使用要比有状态会话Bean的使用多。
项目中没有使用到有状态的会话bean。对于使用的同样数据。也是通过传递參数实现,并不是设置到bean中的属性值中。
对于无状态的会话bean。假设有属性,则可能影响到全部调用的用户,由于他是共享的。
总结
通过实例自己实践之后的清晰了非常多,多动手多动手,TO Do TO DO 。
SSH深度历险(三) EJB Session Bean有状态和无状态的差别与联系的更多相关文章
- SSH深度历险(三) EJB Session Bean有状态和无状态的区别与联系
刚开始对两种sessionbean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后,会发现,事实 ...
- SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)
接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- JavaEE(8) - 本地和远程调用的有状态以及无状态Session EJB
1. 使用NetBeans开发Session Bean #1. 创建项目:File-->New Project-->Java EE-->EJB Module #2. 在项目中创建Se ...
- 有状态与无状态 cookie session
服务器所维护的与客户交互活动的信息称为状态信息.不保存任何状态信息的服务器称为无状态服务器(stateless server),反之则称为有状态服务器(stateful server). 面向连接对应 ...
- SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式
在java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依 ...
- SSH深度历险(二) Jboss+EJB的第一个实例
学习感悟:每次学习新的知识,都会通过第一个小的实例入手,获得成就感,经典的Hello Workd实例奠定了我们成功的大门哈,这些经典的实例虽小但是五脏俱全呢,很好的理解了,Ejb的核心. 今天主要以这 ...
- SSH深度历险(六) 深入浅出----- Spring事务配置的五种方式
这对时间在学习SSH中Spring架构,Spring的事务配置做了详细总结,在此之间对Spring的事务配置只是停留在听说的阶段,总结一下,整体把控,通过这次的学习发觉Spring的事务配置只要把思路 ...
- SSH深度历险(九) Struts2+DWZ+Uploadify实现多文件(文件和图片等等)上传
在gxpt_uas系统中,要实现文件(文件和图片等等,可以灵活配置)的批量上传至mongodb,在学习这个过程中,学习了mongodb,并实现了批量上传的功能,实现思路:在DWZ的基础上参考官方的实例 ...
随机推荐
- uva10791 uva10780(分解质因数)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- SQL Server :理解GAM和SGAM页
原文:SQL Server :理解GAM和SGAM页 我们知道SQL Server在8K 的页里存储数据.分区就是物理上连续的8个页.当我们创建一个数据库,数据文件会被逻辑分为页和区,当用户对象创建时 ...
- MySQL 存储过程和函数(转)
概述 一提到存储过程可能就会引出另一个话题就是存储过程的优缺点,这里也不做讨论,一般别人问我我就这样回答你觉得它好你就用它.因为mysql中存储过程和函数的语法非常接近所以就放在一起,主要区别就是函数 ...
- 重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础
原文:重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础 [源码下载] 重新想象 Windows 8 Store Apps (9) - 控件之 Sc ...
- [Windows Phone] 地图控制项的经纬度
原文:[Windows Phone] 地图控制项的经纬度 前言 本文主要示范如何使用地图经纬度以及显示地标和行人街道,并透过卷轴控制地图缩放比例的功能. ? 实作 step1 建立专案. ? step ...
- 编译Android源代码与内核总结
这些天花了些时间自己下载了android源代码来编译,当中走了一些弯路导致耗了些时间,如今又一次梳理总结下,让有同样想法的人自己编译的时候能少走些弯路,官方指导文档在http://source.and ...
- lunix shell 基础经常使用整理
1 ps -ef 显示正在执行的进程,pid 等信息 UID PID PPID C STIME TTY TIME CMD root 1 0 0 03:45 ? 00:00:02 ini ...
- jquery 如何动态绑定传递到后台上传组件参数
$("#upload_photo").uploadify({ 'auto' : false, 'method' : "post", 'height' : 20, ...
- OpenVPN-ng,为移动续航的应用层隧道
VPN,让人觉得它总是做好事的,是逃离监管的途径,其实VPN已经成了逃离监管的唯一代名词.你看,无论是什么技术,IPSec也好,WEB代理也罢,仅仅要是加密了原始信息的技术,都能够叫做VPN,于是乎就 ...
- Shrio登陆验证实例详细解读(转)
摘要:本文采用了Spring+SpringMVC+Mybatis+Shiro+Msql来写了一个登陆验证的实例,下面来看看过程吧!整个工程基于Mavevn来创建,运行环境为JDK1.6+WIN7+to ...