Java EE 6企业级应用开发教程:第8章 会话Bean

上传人:博****1 文档编号:570176151 上传时间:2024-08-02 格式:PPT 页数:99 大小:1.46MB
返回 下载 相关 举报
Java EE 6企业级应用开发教程:第8章 会话Bean_第1页
第1页 / 共99页
Java EE 6企业级应用开发教程:第8章 会话Bean_第2页
第2页 / 共99页
Java EE 6企业级应用开发教程:第8章 会话Bean_第3页
第3页 / 共99页
Java EE 6企业级应用开发教程:第8章 会话Bean_第4页
第4页 / 共99页
Java EE 6企业级应用开发教程:第8章 会话Bean_第5页
第5页 / 共99页
点击查看更多>>
资源描述

《Java EE 6企业级应用开发教程:第8章 会话Bean》由会员分享,可在线阅读,更多相关《Java EE 6企业级应用开发教程:第8章 会话Bean(99页珍藏版)》请在金锄头文库上搜索。

1、第8章会话Bean吉林大学软件学院本章内容安排:会话会话BeanBean分类分类会话会话BeanBean组成组成无状态会话无状态会话BeanBean开发方法开发方法有状态会话有状态会话BeanBean开发方法开发方法单例会话单例会话BeanBean开发方法开发方法多接口会话多接口会话BeanBean会话会话BeanBean异步调用异步调用8.1会话Bean分类1 1. .无无状态会话状态会话BeanBean无状态会话Bean不维持和客户端的会话状态。当方法结束的时候,客户端特定的状态就不会被保持。允许EJB容器将一个实例分配给任意一个客户端。图8-1无状态会话Bean实例与客户端对应关系8.1

2、会话Bean分类2.2.有有状态会话状态会话BeanBean 有状态会话Bean是一种保持会话状态的服务,每个实例都与特定的客户端相关联,在与客户端的方法调用之间维持对话状态。Server客户端客户端客户端第2次调用第1次调用8.1会话Bean分类3 3. .单例单例会话会话BeanBean 单例会话Bean在每个应用程序中只被实例化一次,在整个应用程序的生命周期中存在。单例会话Bean提供了和无状态会话Bean类似的功能,区别是单例会话Bean在每个应用程序中只有一个实例,而无状态会话Bean会有一个实例池。图8-3单例会话Bean实例与客户端对应关系8.2 会话Bean组成业务接口远程接口

3、本地接口EJB实现类图8-4会话Bean结构8.3 无状态会话Bean开发方法8.3.18.3.1无状态会话无状态会话BeanBean例子例子8.3.1.18.3.1.1实现远程接口的无状态会话实现远程接口的无状态会话BeanBean1、创建一个实现远程接口的无状态会话Bean步骤:(1)创建远程接口,并加入业务方法声明;使用Remote表示一个远程业务接口。作为RMI协议的一部分,方法参数按值传递,并且需要序列化。(2)创建实现远程接口Bean类,并加入已经声明的业务方法的实现代码;使用stateless表示无状态会话Bean。例子:Bean类实现远程接口,其功能是输入字符串参数,并打印“H

4、ello,参数”,最后客户端采用JNDI远程调用EJB。8.3 无状态会话Bean开发方法/创建远程接口packagejavaee.ejb.stateless.remote;importjavax.ejb.Remote;RemotepublicinterfaceHelloBeanRemotepublicStringsayHello(Stringname);8.3 无状态会话Bean开发方法/创建实现远程接口Bean类packagejavaee.ejb.stateless.remote;importjavax.ejb.LocalBean;importjavax.ejb.Stateless;Sta

5、telesspublicclassHelloBeanimplementsHelloBeanRemotepublicHelloBean()/TODOAuto-generatedconstructorstubpublicStringsayHello(Stringname)returnHello+name+!;8.3 无状态会话Bean开发方法2.无状态会话Bean部署8.3 无状态会话Bean开发方法8.3 无状态会话Bean开发方法3.无状态会话Bean客户端通过JNDI引用会话Bean在客户端通过JNDI访问会话Bean的远程接口的方法有两种:1)使用通用JNDI API2)使用EJB Cli

6、ent API8.3 无状态会话Bean开发方法1)、使用通用JNDI APIpublicclassStatelessRemoteClientpublicstaticvoidmain(Stringargs)throwsExceptionPropertiesprop=newProperties();/服务器的命名和目录管理地址prop.put(Context.PROVIDER_URL,remote:/localhost:4447);/初始化上下文环境工厂prop.put(Context.INITIAL_CONTEXT_FACTORY,org.jboss.naming.remote.client.

7、InitialContextFactory.class.getName();/用户验证prop.put(Context.SECURITY_PRINCIPAL,System.getProperty(username,testJNDI);prop.put(Context.SECURITY_CREDENTIALS,System.getProperty(password,123456);tryContextctx=newInitialContext(prop);8.3 无状态会话Bean开发方法1)使用通用JNDI APIObjectobj=ctx.lookup(SessionEJB/HelloBea

8、n!javaee.ejb.stateless.remote.HelloBeanRemote);/*实际访问的是java:jboss/exported/SessionEJB/HelloBean!javaee.ejb.stateless.remote.HelloBeanRemote*/HelloBeanRemotehwr=(HelloBeanRemote)obj;Stringsay=hwr.sayHello(JilinUniversity);System.out.println(say);catch(Exceptione)e.printStackTrace();8.3 无状态会话Bean开发方法3

9、.无状态会话Bean客户端通过JNDI引用会话Bean2)使用EJB Client APIa)新建一个普通Java Project工程,把jboss-client.jar加入到项目;b)将HelloBeanRemote.java文件按照原有路径拷贝到本工程中;c)创建客户端测试文件StatelessRemoteClient.java (带有main函数),如程序清单8-3所示;d)在src目录下添加“jboss-ejb-client.properties”文件。其内容如程序清单8-4所示:publicclassStatelessRemoteClientpublicstaticvoidmain(

10、Stringargs)/在JBoss中使用如下方式访问EJBHashtablejndiProperties=newHashtable();jndiProperties.put(Context.URL_PKG_PREFIXES,org.jboss.ejb.client.naming);tryContextcontext=newInitialContext(jndiProperties);finalStringappName=;finalStringmoduleName=SessionEJB;finalStringdistinctName=;程序清单8-3StatelessRemoteClient

11、.javaObjectobj=context.lookup(ejb:+appName+/+moduleName+/+distinctName+/HelloBean!javaee.ejb.stateless.remote.HelloBeanRemote);HelloBeanRemotehwr=(HelloBeanRemote)obj;Stringsay=hwr.sayHello(JilinUniversity);System.out.println(say);catch(NamingExceptione)e.printStackTrace();程序清单8-3StatelessRemoteClie

12、nt.javaendpoint.name=client-endpointremote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=falseremote.connections=defaultremote.connection.default.host=localhostremote.connection.default.port=4447remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

13、remote.connection.default.username=wxyremote.connection.default.password=123456程序清单8-4jboss-ejb-client.properties图8-11运行结果图8.3 无状态会话Bean开发方法8.3.1.28.3.1.2实现本地接口的无状态会话实现本地接口的无状态会话BeanBean1.创建一个实现本地接口的无状态会话Bean步骤: 1)使用Local创建本地接口,并加入业务方法声明; 2)创建实现本地接口Bean类,并加入已声明的业务方法的实现代码;使用stateless表示无状态会话Bean。例子:实现

14、本地接口的例子:实现本地接口的EJBEJB实现实现2 2个数的加法运算功能,个数的加法运算功能,实现远程接口的实现远程接口的EJBEJB调用调用实现本地接口的实现本地接口的EJBEJB,最后最后客户端采用客户端采用JNDIJNDI远程远程调用实现远程接口调用实现远程接口的的EJB EJB 。/创建本地接口packagejavaee.ejb.stateless.local;importjavax.ejb.Local;LocalpublicinterfaceCalculatorBeanLocalpublicintadd(intx,inty);程序清单8-5CalculatorBeanLocal.j

15、ava/创建实现本地接口Bean类packagejavaee.ejb.stateless.local;importjavax.ejb.LocalBean;importjavax.ejb.Stateless;StatelesspublicclassCalculatorBeanimplementsCalculatorBeanLocalpublicCalculatorBean()/TODOAuto-generatedconstructorstubpublicintadd(intx,inty)System.out.println(ntCalculatorBeanadd()invoked.);retur

16、n(x+y);程序清单8-6CalculatorBean.java8.3 无状态会话Bean开发方法2.实现远程接口的会话Bean通过依赖注入引用本地会话Beanpackagejavaee.ejb.stateless.local;importjavax.ejb.*;RemotepublicinterfaceCallerRemotepublicStringtestMethod();publicStringcallEJBOne(inta,intb);程序清单8-7CallerRemote.javapackagejavaee.ejb.stateless.local;.Statelesspublicc

17、lassCallerBeanimplementsCallerRemoteEJBjavaee.ejb.stateless.local.CalculatorBeanLocallocalbean;publicStringcallEJBOne(inta,intb)intresult=0;trySystem.out.println(nntBeancallEJBOne(a,b)called.);result=localbean.add(a,b);catch(Exceptione)e.printStackTrace();returnDONE-result=+result;程序清单8-8CallerBean.

18、javapackagejavaee.ejb.statelessclient;importjavax.naming.*;importjava.util.*;publicclassStatelessLocalClientpublicstaticvoidmain(Stringargs)throwsExceptionStringresult=;System.out.println(nntbegin.);tryHashtablejndiProperties=newHashtable();jndiProperties.put(Context.URL_PKG_PREFIXES,org.jboss.ejb.c

19、lient.naming);Contextcontext=newInitialContext(jndiProperties);finalStringappName=;finalStringmoduleName=SessionEJB;程序清单8-9TestLocalClient.javafinalStringdistinctName=;System.out.println(ejb:+appName+/+moduleName+/+distinctName+/CallerBean!javaee.ejb.stateless.local.CallerBeanRemote);CallerBeanRemot

20、eremote=(CallerBeanRemote)context.lookup(ejb:+appName+/+moduleName+/+distinctName+/CallerBean!javaee.ejb.stateless.local.CallerBeanRemote);result=remote.callEJBOne(1000,2000);/remote.testMethod();catch(Exceptione)e.printStackTrace();System.out.println(ONE-result=+result);程序清单8-9TestLocalClient.java图

21、8-12运行结果图8.3 无状态会话Bean开发方法8.3.1.38.3.1.3无接口的无状态会话无接口的无状态会话BeanBean EJB 3.1允许会话Bean没有实现任何接口,这种会话Bean称为无接口会话Bean,从而用户不用编写独立的业务接口就可以获得相同的企业Bean功能。例子:无接口会话例子:无接口会话BeanBean实现实现hellohello功能,并使功能,并使用用servletservlet调用调用无接口会话无接口会话BeanBean。packagejavaee.ejb.stateless.nointerface;importjavax.ejb.LocalBean;impo

22、rtjavax.ejb.Stateless;StatelesspublicclassNoInterfaceHelloBeanpublicNoInterfaceHelloBean()publicStringsayHello(Strings)Stringmessage=hello:+s;returnmessage;程序清单8-10NoInterfaceSessionBean发布后的JNDI名字publicclassTestEJBServletextendsHttpServlet/注入EJBEJB privatejavaee.ejb.stateless.nointerface.NoInterface

23、HelloBeanhello;protectedvoiddoGet(HttpServletRequestarg0,HttpServletResponsearg1)throwsServletException,IOExceptionthis.doPost(arg0,arg1);程序清单 8-11 TestEJBServlet.javapublicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)PrintWriterout=null;tryresponse.setContentType(text/html;chars

24、et=UTF-8);out=response.getWriter();out.println();out.println();out.println(ServletcallnointerfaceEJB);out.println();out.println();Stringresult=;result=hello.sayHello(JilinUniversity);.程序清单8-11TestEJBServlet.java图8-13程序运行结果图8.3 无状态会话Bean开发方法8.3.38.3.3无状态会话无状态会话BeanBean的生命事件的生命事件在无状态会话Bean的整个生命周期中,有两个

25、重要事件:PostConstruct和PreDestroy。PostConstruct事件在组件对象被生成的瞬间触发,通常用于对整个无状态会话Bean组件对象状态进行初始化。PreDestroy事件发生在组件对象将要被销毁的前一瞬间,通常用于释放组件对象使用过的资源。在整个EJB组件生命周期中,PostConstruct事件和PreDestroy事件均只会被触发一次。1. PostConstruct事件在无状态会话Bean组件对象创建过程中被触发,表示一个EJB组件对象的生成。通常EJB服务器创建EJB组件对象需要经过三个步骤:EJB容器首先调用EJB组件的Class.newInstance(

26、)方法生成一个组件对象;然后EJB组件服务器会将组件的XML配置文件或类似Resource等标注所包含的初始信息,设置给刚生成的EJB组件对象;最后触发PostConstruct事件,以便进一步进行组件自身状态的初始化。2. PreDestroy事件它是EJB组件对象被销毁过程中的触发事件。在该事件的处理方法结束前,EJB组件对象仍旧是一个完整对象,同样可以进行各种操作和调用。该事件的处理方法结束后,EJB组件上的各种引用就被销毁,组件对象进入等待Java垃圾收集线程的销毁过程。PostConstructPublicvoidinitialEJB()System.out.println(EJBh

27、asbeenconstructed);PreDestroyPublicvoidendEJB()System.out.println(EJBwillbedestroyed);使用标注配置无状态会话Bean生命事件HelloBeaninitialEJBendEJB使用配置文件ejb-jar.xml配置无状态会话Bean生命事件8.3 无状态会话Bean开发方法8.3.28.3.2无状态会话无状态会话BeanBean生命周期生命周期1.无状态会话Bean的三种状态(1).不存在状态 主要针对无状态会话Bean组件对象,而不是EJB组件本身。在此状态下,无状态会话Bean组件对象不存在,但无状态会话B

28、ean组件已经被部署到服务容器中。(2).池状态 在一个无状态会话Bean组件被部署到服务器后,EJB服务器通常会提前创建一定量的无状态会话Bean组件对象,并将它们临时缓存在缓冲区中,这种状态的对象,称为处于池状态的EJB组件对象。(3).调用状态 对应正在为远程或本地客户提供服务的组件对象,这种状态又称为服务状态。任何一个客户请求被发送到无状态会话Bean组件时,EJB服务器会首先从无状态会话Bean组件池中查找特定的无状态会话Bean组件对象,并使用这种组件对象为客户请求提供服务,在请求方法完成后,EJB服务器会将提供服务的组件释放到无状态会话Bean组件的对象池中。因此当远程客户连续对

29、同一个无状态会话Bean组件进行访问时,很可能由两个完全不同的组件对象提供服务。8.4有状态会话Bean开发方法8.4.18.4.1有状态会话有状态会话BeanBean例子例子有状态会话Bean的开发和无状态会话Bean的开发方法完全相同,唯一差别是有状态会话Bean需要维持状态。例子:使用有状态会话例子:使用有状态会话BeanBean实现不断乘实现不断乘2 2的的功能功能。packagejavaee.ejb.stateful.remote;importjavax.ejb.Remote;RemotepublicinterfaceMulBy2Remotepublicintmul();public

30、voidcancel();程序清单8-14MulBy2Remote.javapackagejavaee.ejb.stateful.remote;importjavax.ejb.LocalBean;importjavax.ejb.Stateful;StatefulpublicclassMulBy2BeanimplementsMulBy2Remoteinti=1;publicMulBy2Bean()/TODOAuto-generatedconstructorstubpublicintmul()i=i*2;returni;程序清单8-15MulBy2Bean.javaRemovepublicvoid

31、cancel()i=0;System.out.println(重置i=+i); PreDestroypublicvoidendEJB()System.out.println(predestroy is called); publicclassMulBy2Clientpublicstaticvoidmain(Stringargs)/TODOAuto-generatedmethodstubHashtablejndiProperties=newHashtable();jndiProperties.put(Context.URL_PKG_PREFIXES,org.jboss.ejb.client.na

32、ming);tryContextcontext=newInitialContext(jndiProperties);finalStringappName=;finalStringmoduleName=SessionEJB;finalStringdistinctName=;程序清单8-16MulBy2Client.java/生成第一个实例Objectobj=context.lookup(ejb:+appName+/+moduleName+/+distinctName+/MulBy2Bean!javaee.ejb.stateful.remote.MulBy2Remote?stateful);Mul

33、By2RemotemulBy2R1=(MulBy2Remote)obj;/生成第二个实例obj=context.lookup(ejb:+appName+/+moduleName+/+distinctName+/MulBy2Bean!javaee.ejb.stateful.remote.MulBy2Remote?stateful);程序清单8-16MulBy2Client.java/第一个实例调用2次乘法操作MulBy2RemotemulBy2R2=(MulBy2Remote)obj;intj1=mulBy2R1.mul();j1=mulBy2R1.mul();System.out.printl

34、n(thevalueinClinet1:+j1);/第二个实例调用1次乘法操作intj2=mulBy2R2.mul();System.out.println(thevalueinClinet2:+j2);catch(NamingExceptione)e.printStackTrace();程序清单8-16MulBy2Client.java图8-15运行结果图无、有状态会话Bean代码上区别有状态会话Bean中的bean类具有类似于普通Java类中属性的属性字段(例如i),可以通过bean的业务方法对其进行修改。每个有状态会话bean必须至少定义一个使用Remove注解标记的方法,客户端将使用这

35、些方法来结束与有状态会话bean的会话。调用了一个这样的方法之后,服务器将销毁bean实例。8.4有状态会话Bean开发方法8.4.28.4.2有状态会话有状态会话BeanBean生命周期生命周期图8-16 有状态会话Bean的生命周期当一个客户向EJB服务器请求一个组件引用时,EJB组件对象被服务器创建;当容器生成一个实例时,将把它指定给一个客户端,这样每个从这个客户端来的请求都会被传递给同一个实例,因此有状态会话Bean的生命周期由客户端决定。在客户端使用组件过程中,EJB组件对象一直存在;假如客户端长时间没有调用它的bean实例,容器将在JVM内存溢出前把实例清除,并持久化这个实例的状态

36、,这一过程称为钝化。而当客户端需要的时候再重新加载进内存,这一过程称为活化。EJB容器自动管理着Bean实例的钝化和活化。当客户端放弃EJB组件引用时,对应的EJB组件对象会被EJB容器销毁。8.4有状态会话Bean开发方法8.4.48.4.4有状态会话有状态会话BeanBean生命周期事件生命周期事件1. PostConstruct事件2. PreDestroy事件3. PrePassivate事件4. PostActive事件8.4有状态会话Bean开发方法1. PostConstruct事件 当用户第一次调用某个有状态会话Bean时,EJB服务器会调用newInstance()方法创建一

37、个EJB组件对象。后面过程和无状态会话Bean类似,EJB服务器会对该有状态会话Bean实例进行初始化设置,并触发PostConstruce事件。 由于有状态会话Bean实例在构造过程中,系统会调用一个不带任何参数的构造方法,因而要求有状态会话Bean组件必须提供一个不带任何参数的默认构造方法,否则组件对象在过程中会产生异常。8.4有状态会话Bean开发方法2. PreDestroy事件 当有状态会话Bean对象在活动状态或者挂起状态时,客户端可以通过调用组件的Remove方法实现组件对象的销毁;或者在活动状下的组件对象超过其寿命,服务器也会销毁该组件对象,将该组件对象由活动状态转变为不存在状

38、态。 当有状态会话Bean实例被销毁前,EJB服务器触发组件上的PreDestroy事件。PreDestroy是组件整个生命周期中最后执行的行为,在方法中可以对组件用过的资源进行释放。8.4有状态会话Bean开发方法3. PrePassivate事件 当一个处于活动状态的有状态会话Bean对象长时间不使用时,EJB服务器通常会将该组件对象切换到休眠状态(钝化)。EJB组件休眠的本质是将EJB组件对象的状态和当前环境状态统一保存起来,然后将对象从内存中删除。 在状态会话Bean对象由活动状态转变到休眠状态时,EJB服务器会触发PrePassivate。在该方法中可以对一些休眠前的状态进行保存。8

39、.4有状态会话Bean开发方法4. PostActive事件 当有状态会话Bean对象由休眠状态切换到活动状态后,会马上触发EJB组件上的PostActive事件。在该方法中可以对EJB组件中的状态进行一些休眠后的恢复工作。PostConstructpublicvoidinitEJB()System.out.println(“EJBinitializing”)PrePassivatepublicvoidprePassivate()System.out.println(“EJBprePassivate”)PostActivatepublicvoidpostActivate()System.out

40、.println(“EJBpostActivate”)PreDestroypublicvoidpreDestroy()System.out.println(“EJBpreDestroy”)8.4有状态会话Bean开发方法8.4.38.4.3与无状态会话与无状态会话BeanBean区别区别(1)组件对象进入休眠(缓存状态)的时刻有状态会话Bean进入休眠状态,通常是因为对应的组件对象长时间不被使用,或服务器负载十分重的情况下才会发生;而无状态会话Bean在一个方法执行完毕后就会被释放到实例池中。(2)组件对象在休眠状态或缓存状态的差别无状态会话Bean进入缓存状态后,其对应的对象在服务器上还存在

41、;而有状态会话Bean对象进入休眠状态后,其EJB组件对象被销毁,只是其对象状态被保存到了硬盘或数据库中。8.4有状态会话Bean开发方法(3)组件对象进入休眠或(缓存状态)时,EJB服务器所保留的组件数据 无状态会话Bean组件对象进入缓存状态后,其被保留的是组件上下文环境;而有状态会话Bean组件对象进入休眠状态时被保存的不但是EJB组件的上下文环境,而且还包括EJB组件的各种属性状态。8.5单例会话Bean开发方法8.5.18.5.1单例会话单例会话BeanBean例子例子使用Singleton标注创建单例会话Bean。例子:例子:创建创建一个功能很简单的单例会话一个功能很简单的单例会话

42、BeanBean,要求两个客户共享一个变量,当一个客户,要求两个客户共享一个变量,当一个客户端修改变量时,验证另一个客户端访问该变端修改变量时,验证另一个客户端访问该变量的值是否发生变化。量的值是否发生变化。packagejavaee.ejb.singleton.remote;importjavax.ejb.Remote;RemotepublicinterfaceSimpleSingletonRemotepublicvoidchange01();publicintgetValue();程序清单8-18SimpleSingletonRemote.javaSingletonpublicclassS

43、impleSingletonBeanimplementsSimpleSingletonRemoteinti=0;publicSimpleSingletonBean()/TODOAuto-generatedconstructorstubpublicvoidchange01()if(i=0)i=1;elsei=0;publicintgetValue()returni;程序清单8-19SimpleSingletonBean.javapublicclassSimpleSingletonClientpublicstaticvoidmain(Stringargs)HashtablejndiProperti

44、es=newHashtable();jndiProperties.put(Context.URL_PKG_PREFIXES,org.jboss.ejb.client.naming);tryContextcontext=newInitialContext(jndiProperties);finalStringappName=;finalStringmoduleName=Singleton;finalStringdistinctName=;/生成2个客户端SimpleSingletonRemotesingle01=(SimpleSingletonRemote)context.lookup(ejb:

45、+appName+/+moduleName+/+distinctName+/SimpleSingletonBean!javaee.ejb.singleton.remote.SimpleSingletonRemote);SimpleSingletonRemotesingle02=(SimpleSingletonRemote)context.lookup(ejb:+appName+/+moduleName+/+distinctName+/SimpleSingletonBean!javaee.ejb.singleton.remote.SimpleSingletonRemote);intvalue1=

46、single01.getValue();intvalue2=single02.getValue();System.out.println(Singleton01初始值:+String.valueOf(value1);System.out.println(Singleton02初始值:+String.valueOf(value2);single01.change01();value1=single01.getValue();value2=single02.getValue();System.out.println(Singleton01值:+String.valueOf(value1);Syst

47、em.out.println(Singleton02值:+String.valueOf(value2);single02.change01();value1=single01.getValue();value2=single02.getValue();System.out.println(Singleton01值:+String.valueOf(value1);System.out.println(Singleton02值:+String.valueOf(value2);catch(NamingExceptione)e.printStackTrace();图8-18运行结果图8.5单例会话Be

48、an开发方法8.5.28.5.2单例会话单例会话BeanBean的并发控制的并发控制1. 容器管理并发CMCEJB容器控制客户端访问单例会话Bean的业务方法,其使用Lock标注来指定当客户端调用方法是容器如何管理并发。Lock的值可以为READ和WRITE。 它是默认管理方式,相当于在所有业务方法之上的写锁定(write lock)8.5单例会话Bean开发方法Lock(LockType.WRITE):这是一个排它锁,对其他客户锁定正在调用的方法,直至这个方法被调用完毕。例如客户端C1调用了这个带有排它锁的方法,客户端C2将不能调用这个方法直至C1调用完成。Lock(LockType.REA

49、D):这是共享锁,允许多个客户并发访问或共享。例如两个客户端C1和C2可以同时调用那个带有共享锁的方法。Packagejavaee.ejb.singleton;ConcurrentcyManagement(ConcurrencyManagementType.CONTAINER)SingletonPublicclassSingletonCMCBean()privateStringstate;Lock(LockType.READ)AccessTimeout(value=20,unit=TimeUnit.SECONDS)publicStringgetState()returnstate;容器管理并发

50、例子AccessTimeout(value=20,unit=TimeUnit.SECONDS)Lock(LockType.WRITE)publicvoidsetState(StringaState)state=aState;tryCountDownLatchlatch=newCountDownLatch(1);latch.await(10,TimeUnit.SECONDS); catch(Exceptione)System.out.println(写锁出现错误); 容器管理并发例子8.5单例会话Bean开发方法2. Bean管理并发BMC 需要使用ConcurrencyManagement(B

51、EAN),并且利用Java编程语言的同步原语进行同步控制,例如synchronized和volatile。Packagejavaee.ejb.singleton;ConcurrentcyManagement(ConcurrencyManagementType.BEAN)SingletonPublicclassSingletonBMCBean()privateStringstate;publicStringgetState()returnstate;Bean管理并发例子publicsynchronizedvoidsetState1(StringaState)state=aState;public

52、voidsetState2(Statestate)synchronized(this)this.state=state; Bean管理并发例子protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)simulationContainerManaged.setState(SimulationContainerManaged.State.PAUSED);simulationBeanManaged.setState1(SimulationBeanManaged.State.RUNNING);.

53、out.println(SimulationContainerManagedState:+simulationContainerManaged.getState()+); out.println(SimulationBeanManagedState:+simulationBeanManaged.getState()+); 使用Servlet调用并发Bean程序运行结果分析:打开两个浏览器后,运行刚刚建立的Servlet,会发现2个浏览器显示的结果是按照打开浏览器的顺序依次显示结果的,而且有一定的延迟。8.5单例会话Bean开发方法8.5.38.5.3单例会话单例会话BeanBean生命周期生命

54、周期单例会话bean与无状态会话bean在大体上是一样的,只不过对于单例会话bean在实例池中只有一个实例存在,而对于无状态会话Bean来说,在实例池中存在多个实例。8.6 多接口会话Bean 一个会话Bean可以实现多个Remote型或者Local型接口,这类似于一个类实现了多个接口的情况。但不能在同一个接口上既但不能在同一个接口上既使用使用RemoteRemote,又使用,又使用LocalLocal。8.6 多接口会话Bean例子:例子:开发一个多接口会话开发一个多接口会话BeanBean,使其实,使其实现两个远程接口和一个本地接口现两个远程接口和一个本地接口。packagejavaee.

55、ejb.mulinterface.remote;importjavax.ejb.Remote;RemotepublicinterfaceHelloRemotepublicStringsayHelloFromRemote(Stringname);程序清单8-23 HelloRemote.javapackagejavaee.ejb.mulinterface.remote;importjavax.ejb.Local;LocalpublicinterfaceHelloLocalpublicStringsayHelloFromLocal(Stringname);程序清单8-24 HelloLocal.j

56、avapackagejavaee.ejb.mulinterface.remote;importjavax.ejb.Remote;RemotepublicinterfaceMulBy2Remotepublicintmul();publicclassMulInterfaceBeanimplementsHelloRemote,HelloLocal,MulBy2Remoteintvalue=1;/生成本地接口实例EJBjavaee.ejb.mulinterface.remote.HelloLocalhello;publicMulInterfaceBean()/TODOAuto-generatedcon

57、structorstubpublicStringsayHelloFromLocal(Stringname)returnHello+name+fromlocal!;publicStringsayHelloFromRemote(Stringname)Stringresult=null;result=hello.sayHelloFromLocal(name);returnresult;publicintmul()value=value*2;returnvalue;8.7 会话Bean异步调用默认情况下,通过远程接口、本地接口或无接口视图调用会话Bean是同步的通信方式:客户端调用一个方法,然后客户端

58、被阻塞,直到被调用方法处理完成返回结果给客户端,客户端才能继续以下的工作。在EJB 3.1之前,异步调用只能通过JMS和MDB来实现。在EJB 3.1规范中,你可以在一个会话Bean的方法上添加一个javax.ejb.Asynchronous标注来实现异步调用。8.7 会话Bean异步调用例子例子:以网络打印为例,讲述会话Bean异步调用的工作方式。当网络打印一个文件时,打印完成时间依赖于打印机是否空闲,是否有足够的纸,网络是否通畅等,因此网络打印是一个很花时间的任务。当客户端调用一个方法来打印文件时,他希望调用后不用等待,可以继续执行其他的任务,使用会话Bean异步调用机制进行网络打印的代码

59、如下所示。StatelessLocalBeanpublicclassPrintBeanAsynchronouspublicvoidprintAndForget()System.out.println(*printAndForget*);AsynchronouspublicFutureprintAndCheckLater()System.out.println(*printAndCheckLater*);returnnewAsyncResult(OK);程序清单程序清单8-27 PrintBean.java8-27 PrintBean.java当客户端调用 printAndForget ()和p

60、rintAndCheckLater ()时,容器会立即返回控制权给客户端,客户端可以继续其他的任务,而被调用的任务会在另外一个线程中被执行。javax.ejb.AsyncResult实现了Future接口publicclassPrintServletextendsHttpServletEJBjavaee.ejb.asyncall.PrintBeanprintBean;protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOExceptio

61、nresponse.setContentType(text/html;charset=UTF-8);PrintWriterout=response.getWriter();try/调用printAndForget方法printBean.printAndForget();out.println();out.println();out.println(ServletPrintServlet);异步调用的返回值类型为void/调用printAndCheckLater方法if(futureResult.isDone()&!futureResult.isCancelled()tryout.println

62、(printAndCheckLaterexecuted-Result:+futureResult.get()+);catch(ExecutionExceptione)/TODOAuto-generatedcatchblocke.printStackTrace(); elseout.println(printAndCheckLaterisnotprepared);异步调用返回值为java.util.concurrent.Future 对象。Future对象允许在另外一个线程中执行的方法返回一个值,而客户端可以使用Future.get()方法来获得结果, 使用Future.cancel()方法终止

63、调用。图8-20 运行结果图结果分析:由于EJB异步调用使用Java的线程机制实现异步通信,在servlet中不需要等待线程执行完毕,就已经执行到if(futureResult.isDone()&!futureResult.isCancelled()代码处执行代码处执行判断,这时线程没有结束,因此返回值为判断,这时线程没有结束,因此返回值为false,执行,执行else语句。语句。思考题如何在客户端获得EJB异步调用方式的结果?Request.getSesion.setAttribute();会话Bean的分类无状态会话Bean(Stateless)有状态会话Bean(Stateful)单例会

64、话Bean(singleton)本地接口(Local)远程接口(Remote)无接口多接口会话Bean的调用远程访问JNDIAPIprop.put(Context.INITIAL_CONTEXT_FACTORY,org.jboss.naming.remote.client.InitialContextFactory.class.getName()Contextctx=newInitialContext(prop);ctx.lookup(“”)EJBClientAPIjboss-ejb-client.properties配置文件prop.put(Context.URL_PKG_PREFIXES,

65、org.jboss.ejb.client.naming);Contextctx=newInitialContext(prop) ;ctx.lookup(“”)本地访问JNDIAPIContextctx=newInitialContext() ;ctx.lookup(“”)依赖注入EJB推荐使用推荐使用8.8 小结会话会话BeanBean分类分类会话会话BeanBean组成组成无状态会话无状态会话BeanBean开发方法开发方法有状态会话有状态会话BeanBean开发方法开发方法单例会话单例会话BeanBean开发方法开发方法多接口会话多接口会话BeanBean会话会话BeanBean异步调用异步调用

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号