`
suhuanzheng7784877
  • 浏览: 702539 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Ff8d036b-05a9-33b5-828a-2633bb68b7e6
读金庸故事,品程序人生
浏览量:47708
社区版块
存档分类
最新评论

JavaEE5学习笔记05-EJB之会话Bean(sessionBean)总结-----2

阅读更多

下面我们修改客户端代码来验证一下无状态会话Bean的变量是怎么回事。

服务端代码修改如下,修改后重新打包部署。

package ejb.sessionBean.impl;

import java.util.HashMap;

import java.util.Map;

import javax.ejb.Stateless;

import ejb.sessionBean.Hello;

 

@Stateless

public class HelloEAOImpl implements Hello {

 

    // 访问次数

    private int num;

 

    private Map<String, Integer> buyInfo = new HashMap<String, Integer>();

 

    @Override

    public String hello(String name) {

 

       return "欢迎你:" + name;

    }

 

    @Override

    public int countNum() {

       num++;

       return num;

    }

 

    public void addItem(String item) {

       if (buyInfo.containsKey(item)) {

           buyInfo.put(item, buyInfo.get(item) + 1);

       } else {

           buyInfo.put(item, 1);

       }

       System.out.println("Stateless-buyInfo:" + buyInfo);

    }

 

}

测试代码增加几个方法如下

    public void test02() throws NamingException {

       context = init();

       Hello hello = (Hello) context.lookup("HelloEAOImpl/remote");

       System.out.println("test02访问" + hello.countNum());

       System.out.println("test02访问" + hello.countNum());

       System.out.println("test02访问" + hello.countNum());

       System.out.println("test02访问" + hello.countNum());

       System.out.println("test02访问" + hello.countNum());

    }

 

    public void test03() throws NamingException {

       context = init();

       Hello hello = (Hello) context.lookup("HelloEAOImpl/remote");

       System.out.println("test03访问" + hello.countNum());

       System.out.println("test03访问" + hello.countNum());

       System.out.println("test03访问" + hello.countNum());

       System.out.println("test03访问" + hello.countNum());

       System.out.println("test03访问" + hello.countNum());

 

    }

 

    public void test04() throws NamingException {

       context = init();

       Hello hello = (Hello) context.lookup("HelloEAOImpl/remote");

       hello.addItem("叶小钗");

       hello.addItem("一页书");

 

    }

 

    public void test05() throws NamingException {

       context = init();

       Hello hello = (Hello) context.lookup("HelloEAOImpl/remote");

       hello.addItem("一页书");

 

    }

junit单独先执行test02方法之后再执行test03方法结果如下:

test2

test02访问1

test02访问2

test02访问3

test02访问4

test02访问5

test3

test03访问6

test03访问7

test03访问8

test03访问9

test03访问10

之后单独先执行test04之后再执行test05

test04服务端控制台效果如下:

10:22:56,063 INFO  [STDOUT] Stateless-buyInfo:{叶小钗=1}

10:22:56,079 INFO  [STDOUT] Stateless-buyInfo:{一页书=1, 叶小钗=1}

test05

10:24:03,644 INFO  [STDOUT] Stateless-buyInfo:{一页书=2, 叶小钗=1}

由此观之,客户端单线程访问EJB容器的时候,对于客户端来说无状态的会话Bean会将实例变量当做类似于静态变量来处理的。无论是几个客户端,总之只要是非多线程并发访问无状态SessionBean的时候,确实该变量类似于容器全局的静态变量。如果有多个并发访问会如何呢?

我们一气呵成走完junit测试用例(运行2遍)服务端控制台如下。

效果如下:

10:29:00,506 INFO  [STDOUT] Stateless-buyInfo:{一页书=2, 叶小钗=2}

10:29:00,506 INFO  [STDOUT] Stateless-buyInfo:{一页书=3, 叶小钗=2}

10:29:00,538 INFO  [STDOUT] Stateless-buyInfo:{一页书=4, 叶小钗=2}

10:29:19,618 INFO  [STDOUT] Stateless-buyInfo:{叶小钗=1}

10:29:19,634 INFO  [STDOUT] Stateless-buyInfo:{一页书=5, 叶小钗=2}

10:29:19,650 INFO  [STDOUT] Stateless-buyInfo:{一页书=6, 叶小钗=2}

可以看出此时的buyInfo变量不再是单一静态的了,并发访问的时候,对象池会再生出(new)一个新的实例变量,该实例变量的生命是由应用服务器的对象池来管理的。而客户端调用的时候具体获得和调用哪个实例变量,这个不好说,只能看应用服务的JVM调度了。所以来说很多人建议甚至是规定不要在无状态的SessionBean中定义实例变量,服务端无法维护其通讯状态是这个意思!有状态的会话Bean会记录一次会话调用中,实例变量的状态的实质含义就是说保证在客户端获取、调用有状态的Bean时,保证里面的实例变量和上次访问的时候是一样的、是线程安全的、对于你这个客户端来说是独一无二的!因此有状态的开销也是很大的。无状态的对象池仅仅维护并发所产生的这几个变量罢了,但是我无状态的SessionBean可不能保证你客户端下次访问的就一定是你上次所操作的变量哦………………所以一般在无状态的SessionBean中定义实例变量其实没什么意义,因为客户端真正操作的是哪个实例变量,只有对象池根据并发的实际情况而定,所以很不稳定,所以EJB标准给出的结论就是“不允许”在无状态的SessionBean中定义实例变量。

1.      无状态的会话Bean的本地、远程调用

EJB组件都会分为本地调用(local)和远程调用(remote2种。

1)一般客户端程序无论是手机、ATM机、电信的终端设备、web服务器的调用会话Bean的时候都是调用的在另一个地理位置的远程EJB容器中的SessionBean。此时就需要远程调用remote。在接口的类名上加入@Remote注解就可以了。

2)EJB容器内部,EJB组件和EJB组件进行相互调用的时候,那么本身就是“兄弟联”内部的,好说话。此时只需要本地的local方式调用就可以了。在接口的类名上加入@Local注解就可以了。在本地调用的时候其实就是保证在同一个JVM上运行就可以了。

2.      会话Bean的发布

上面提到了SessionBean的打包,下面我们来个截图看看,笔者用的是MyEclipse8.6。打包过程如下

在开发EJB项目右键,export

 

选中EJB的接口和实现类,导出后是一个jar,将此jar包拷贝到${JBOSS_HOME} \server\default下面即可完成EJB的发布。

注:如果EJB调用到了辅助类,此辅助类也需要打包到jar中。还有就是客户端调用此EJB接口的时候,切记接口的包结构一定要和服务端的包结构一致。

  • 大小: 76.1 KB
分享到:
评论

相关推荐

    JavaEE5学习笔记07-Web层与EJB集成总结

    ### JavaEE5学习笔记07-Web层与EJB集成总结 #### 一、JavaEE5框架中的Web层与EJB集成概述 在JavaEE5(即Java Platform, Enterprise Edition 5)中,Web层与EJB(Enterprise JavaBeans)的集成是构建企业级应用的...

    JavaEE5学习笔记02-JNDI与RMI

    在JavaEE环境中,RMI经常与EJB结合使用,尤其是无状态SessionBean,因为它们不需要维持客户端的会话状态,适合RMI的轻量级通信模式。 当一个EJB被标记为远程接口时,它可以通过RMI在不同 JVM(Java Virtual ...

    javaee思维导图版笔记-吉林大学

    "javaee思维导图版笔记-吉林大学" 本笔记主要涵盖了Java EE的基础知识,包括Servlet、JSP、JNDI、JPA等方面的内容。 一、Servlet概述 Servlet是Java EE中的一种服务器端组件,用于处理HTTP请求并返回响应。...

    javaee学习笔记

    - **会话Bean**:在整个用户会话期间保持,用于跟踪用户状态。 - **应用Bean**:在整个应用程序范围内共享,用于全局数据。 **自定义标签(Custom Tags)**提供了一种扩展JSP语法的方式,通过定义标记库描述符(TLD...

    JavaEE2017最新版基础班学习笔记

    包括会话Bean(Session Beans)负责业务逻辑,实体Bean(Entity Beans)作为持久化对象,以及消息驱动Bean(Message-Driven Beans)处理JMS消息。 6. **JMS (Java Message Service)**:JMS允许应用程序之间异步通信...

    Java/JavaEE 学习笔记

    Java/JavaEE 学习笔记 作者在杰普学习时的学习笔记,是J2ee初学者必备手册,是大家学习J2EE开发的很好的参考笔记。 Java/JavaEE 学习笔记 内容目录: Unix 学习笔记..........7 一、Unix前言............7 二、...

    JavaEE学习笔记

    EJB是JavaEE的核心,提供了三种类型的Bean:会话Bean(Session Beans)处理业务逻辑,实体Bean(Entity Beans)代表持久化数据,消息驱动Bean(Message-Driven Beans)处理消息队列。Spring框架则以其依赖注入和面向...

    JavaEE基础笔记.zip

    分为会话Bean(Session Beans)、实体Bean(Entity Beans)和消息驱动Bean(Message-driven Beans),分别处理业务逻辑、持久化数据和消息通信。 5. **JMS(Java Message Service)**:JMS是JavaEE的消息中间件接口...

    J2EE学习笔记(J2ee初学者必备手册)

    第四章 Session Bean(会话Bean).....322 第五章 消息驱动Bean(MDB).........327 EJB3.0.....329 第一章 EJB3.0 Foundation...............329 第二章 Session Bean........................330 第三章 消息驱动Bean...

    达内培训笔记

    - **EJB(Enterprise JavaBeans)**:分为会话Bean(Session Beans)、实体Bean(Entity Beans)和消息驱动Bean(Message-driven Beans),用于实现业务逻辑和持久化数据。 - **JPA(Java Persistence API)与ORM*...

    javaWeb学习笔记+狂神说

    EJB是Java企业级应用的组件模型,分为会话bean、实体bean和消息驱动bean。它们提供了一种在分布式环境中构建可复用的、事务处理的服务器端组件的方法。虽然现代JavaEE应用更多采用轻量级框架如Spring,但了解EJB的...

    JAVA-EE-master (4).zip

    EJB分为三种类型:会话bean(Session Beans)处理客户端请求,实体bean(Entity Beans)代表持久化的业务对象,消息驱动bean(Message-Driven Beans)用于处理JMS消息。 4. **JMS**:Java Message Service允许在...

Global site tag (gtag.js) - Google Analytics