EJB 有状态的对象和无状态的对象

有状态Bean:

@Stateful

@Remote

public class StatefulEjbBean implements StatefulEjb{

private int state;

@Override

public void compute(int i) {

state=state+i;

}

@Override

public int getResult() {

return state;

}

}

无状态Bean:

@Stateless

@Remote

public class StatelessEjbBean implements StatelessEjb {

private int state;

@Override

public void compute(int i) {

state = state + i;

}

@Override

public int getResult() {

return state;

}

}

测试有状态EJB对象:

public class StatefulEjbClient {

public static void main(String[] args) throws Exception {

InitialContext context=new InitialContext();

//第一次会话

StatefulEjb ejb1=(StatefulEjb)context.lookup("StatefulEjbBean/remote");

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

System.out.println("第一次会话结束---------");

//第二次会话

StatefulEjb ejb2=(StatefulEjb)context.lookup("StatefulEjbBean/remote");

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

System.out.println("第二次会话结束---------");

}

}

结果:

0

1

2

3

4

5

第一次会话结束---------

0

1

2

3

4

5

第二次会话结束---------

测试无状态EJB对象:

public class StatelessEjbClient {

public static void main(String[] args) throws NamingException {

InitialContext context=new InitialContext();

//第一次会话

StatelessEjb ejb1=(StatelessEjb)context.lookup("StatelessEjbBean/remote");

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

ejb1.compute(1);

System.out.println(ejb1.getResult());

System.out.println("第一次会话结束---------");

//第二次会话

StatelessEjb ejb2=(StatelessEjb)context.lookup("StatelessEjbBean/remote");

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

ejb2.compute(1);

System.out.println(ejb2.getResult());

System.out.println("第二次会话结束---------");

//判断每次查找到的对象是否一样

System.out.println(ejb1==ejb2);//false

}

}

结果:

11

12

13

14

15

第一次会话结束---------

15

15

16

17

18

19

第二次会话结束---------

结果对比

通过多次执行,发现对于有状态的EJB对象,每次通过查找获得的对象都是新对象;而对于无状态的EJB对象,每次查找获得的对象都有一个单例类的效果,多次执行测试无状态的EJB对象的方法,会发现服务端的貌似始终在对一个对象进行操作。

有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。

无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。 即不能以bean中有无属性等来区分是否有状态的,有状态无状态并非针对session
bean中的状态(成员变量or属性)。

对于有状态会话Bean来说,只要有客户端发送对有状态会话Bean的访问,服务器都会创建一个会话Bean实例与该客户端对应,这样这个实例与这个客户端就是一一对应的。如果客户端在Bean实例中保存了信息,之后还可以使用。 而对于无状态会话Bean来说,服务器端会维持一个实例池,创建好若干个实例对象供客户端调用。当从客户端发送创建会话Bean的请求时,并不一定会真的创建 EJB,多数情况下是从实例池中得到一个实例,用完之后重新放回实例池。如果下次再访问,再从实例池中取出一个实例使用,并不一定是上次的实例。即使两次访问使用的是同一个实例,在两次访问之间也有可能有其他的客户端访问了该实例。所以,并不能保证在多次访问之间的信息会被保存。因此无状态会话Bean不会专门保存也没必要客户端的信息。是否有必要建立一个实例池?spring的singleton
bean也能很好的满足不同用户的每次请求。以目前的知识了解个人暂且认为在session bean方法里面没有需要同步的地方时,没必要维持一个实例池。刚才了解到EJB3.1确实增加了singleton session bean。而在我的测试例子中,Stateless bean好像每次都是同一个实例,这样才会导致后面几次访问都能得到上一次访问中的值,跟singleton一样。

至于有状态和无状态的性能,因为有状态会话Bean需要保存特定客户端的信息,一个客户端对应一个实例,既是在当时客户端有连接没有访问的情况下,也要为这个客户端保留这个实例。这样随着客户端数量的增加,服务器端需要创建的实例的数量也在增加,增加到一定程度对服务器的性能就会有一定的影响。为了不对服务器的性能产生影响,通常服务器会进行一些优化。当客户端的数量超过某个值之后,就不创建新的实例。虽然不创建新的实例,还是需要对用户响应,这时候就采用共享实例的方式。会查看哪个
实例虽然处于连接状态,但是没有访问,然后把这个实例的状态保存起来,使用这个实例为新的请求服务,对于原来的客户端来说,称为挂起。如果原来的客户端又发送请求了,会重新查找一个空闲的实例并且把已经保存好的状态恢复回来,这个过程称为激活。所以在有状态会话Bean的访问过程,经常会发生查找实例,激活挂起等操作,所以效率比较低。而发送对无状态会话Bean的请求的时候,可以随便取一个空闲的实例为客户端服务,所以效率比较高。

有状态会话Bean的好处是,可以保存客户端的状态,所以客户端在后续访问的时候就可以少传递一些参数。而无状态会话Bean需要传递方法执行过程中需要的所有参数。 如果要频繁的访问,并且多次访问之间会共享一些信息,这时候应该使用有状态会话Bean。对于不经常使用的功能,可以使用无状态会话Bean。而无状态会话Bean的使用要比有状态会话Bean的使用多。

时间: 2024-10-12 23:01:55

EJB 有状态的对象和无状态的对象的相关文章

有状态的EJB对象和无状态的EJB对象

一,定义有状态Bean和无状态Bean 有状态Bean: @Stateful @Remote public class StatefulEjbBean implements StatefulEjb{ private int state; @Override public void compute(int i) { state=state+i; } @Override public int getResult() { return state; } } 无状态Bean: @Stateless @R

Java深度历险(二) EJB Session Bean有状态和无状态的区别与联系

刚开始对两种sessionbean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后,会发现,事实恰好相反:有状态和无状态会话bean的本质区别是它们的生命期. 首先解释一个下面要用到的概念--用户:sessionbean 的用户实际上就是直接调用ejb的类的实例,甚至是这个实例的某个方法.同一个类的不同实例对于session bean来说是不同的用户. 实例解析 有状态的StatefulEjb

无状态会话bean(1)---定义

无状态会话bean用于完毕在单个方法的生命周期内的操作.无状态bean能够实现很多业务操作,可是每一个方法都不能假定不论什么其它的方法会在它之前调用.后半句的意思是如今的你可能不是刚才的你.明天的你可也能不是今天的你,这个时候你就叫做"无状态你". 上面的阐述听起来像是无状态的bean的一个局限,好像每次再见就像永别似的. 可是这是迄今为止业务服务最常见的形式,就像去饭店吃饭,点菜的服务员与给你上菜的服务员是不是同一个这不是我们所关心的. 无状态回话bean不同于适合在对话中积累状态(

无状态会话bean(1)---定义(未排版)

无状态会话bean用于完成在单个方法的生命周期内的操作.无状态bean可以实现许多业务操作,但是每个方法都不能假定任何其他的方法会在它之前调用. 这听起来像是无状态的bean的一个局限.但是这是迄今为止业务服务最常见的形式.不同于适合在对话中积累状态(如零售应用程序的购物车)的有状态会话bean,无状态回话bean旨在非常有效的执行独立操作.无状态会话bean可以在最小化对整体服务器资源影响的同时,扩展到大量的客户端. 会话bean定义分为如下两个部分: 零个或多个业务接口,定义了一个客户端在b

HTTP协议是无状态协议,怎么理解?

 Http是一个无状态协议,同一个会话的连续两个请求互相不了解,他们由最新实例化的环境进行解析,除了应用本身可能已经存储在全局对象中的全部信息外,该环境不保存与会话有关的不论什么信息. 自己的理解,在asp.net里:每次提交server的页面没有不论什么关系,每次记录在页面的信息下次提交是记不住的,(除了应用本身可能已经存储在全局对象中的全部信息外)在.net里实际就是ViewState,ViewState是asp.net中保存页面信息的基本单位,应用时就是保存在控件隐藏域等中的数据 协议的状

有状态无状态回话bean

1.有状态(Stateful) 可以在不同的方法调用间保持针对各个客户端的状态 与客户端的联系必须被维持,这样做开销要大一些 有状态也可以这样理解,它存在存储能力,也就是说至少有一个属性来标识它目前的状态,例如: 注意:有状态会话bean,每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”:一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束.即每个用户最初都会得到一个初始的bean. 2.无状态(Stateless) 在不同方法调用间不保留任何状态

Http协议无状态的理解

Http是一个无状态协议,同一个会话的连续两个请求互相不了解,他们由最新实例化的环境进行解析,除了应用本身可能已经存储在全局对象中的所有信息外,该环境不保存与会话有关的任何信息. 自己的理解,在asp.net里:每次提交服务器的页面没有任何关系,每次记录在页面的信息下次提交是记不住的,(除了应用本身可能已经存储在全局对象中的所有信息外)在.net里实际就是ViewState,ViewState是asp.net中保存页面信息的基本单位,应用时就是保存在控件隐藏域等中的数据 协议的状态是指下一次传输

基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类

这段时间做新的Android项目的客户端和和REST API通讯框架架构设计,使用了很多新技术,最终的方案也相当简洁优雅,客户端只需要传Java对象,服务器端返回json字符串,自动解析成Java对象, 无状态安全验证基于JWT实现,JWT规范的细节可以参考我前面的文章.JWT的token和数据防篡改签名统一放在HTTP Header中,这样就实现了对请求内容和返回结果的无侵入性,服务器端也可以在全局过滤器中统一处理安全验证. Android客户端使用了Volley网络请求框架和Gson解析库,

有状态bean和无状态的bean

有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即"有状态":一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束.即每个用户最初都会得到一个初始的bean. 无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用.即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用.由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean.但无状态会话bean 并非没有