J2EE培训_3.doc_第1页
J2EE培训_3.doc_第2页
J2EE培训_3.doc_第3页
J2EE培训_3.doc_第4页
J2EE培训_3.doc_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

J2EE培训 第十一章一 JMS介绍1. 特点:是由消息系统提供满足规范的方法连接应用中不同的组件。采用异步方式传递消息,客户机不必等待处理的过程可以继续处理,同时支持事务特性。2. 组成:l JMS客户端:发送和接收消息的客户端Java程序l 消息 :JMS应用中在不同客户端传递的消息l JMS提供者:实现JMS的消息系统,并且提供控制和管理功能。l 管理对象:管理对象是预定义的JMS队形,客户端使用这些预定义的对象通信。例如后面介绍的连接工厂。3. 种类l 点到点通信(PTP):当一个消息生产者发送消息到一个确定的消息消费者时,点对点消息传递发生。点对点的消息传递由JMS消息队列管理。消息生产者成为队列发送器,消息消费者成为队列接收器。l 发布订阅机制(Pub/Sub):当消息生产者发送消息到多个消息消费者时,发布订阅消息传递发生。公布和发生由消息主题(topic)管理。消息生产者成为主题公布者,消息消费者称为主题预定者。4. 消息的持久性:消息可分为持久的和非持久的。持久性消息被保证至少被传递一次,在它被成功写道一个持久数据存储中(在weblogic中是一个磁盘文件或是一个支持JDBC数据库)。才认为是被传递的。非持久性消息也保证至少被传递一次,但是如果系统失败,消息可能丢失。非持久性在消息被接受后就认为是被成功传递的。5. 连接工厂:定位消息服务的驱动程序,为指定的消息服务器和系统配置产生JMS连接。6. 连接:连接是应用程序与JMS的通信连接。连接从工厂获得,并为管理消息传递交互创建客户端和服务端必须的资源。7. 目的:表示接收方式8. 会话:接收和发送消息的会话线程9. 消息生产者:会话使用它把消息发送到目的地。10. 消息消费者:会话使用它从目的地接收消息生产者发送的消息。11. 消息的组成l 消息头:所有的消息都支持相同的消息头,客户端可以使用消息头唯一标识消息和路由信息。l 属性:可以使用属性添加额外的消息头内容。l 消息体:包含具体的消息内容12. 消息的类型:JMS定义了五种格式的消息体:l StreamMessage:消息由串行化的消息对象组成,必须按照设置时的顺序来读取对象。l MapMessage:消息由名称/值对组成,其中名称为字符串类型,值为Java数据类型。可以使用列举顺序读取消息的值。也可以通过名称无序的获取值。l TextMessage:消息的主体为字符串。l ObjectMessage:消息的主体为串行化的Java对象,可以是自己定义的Java对象。l BytesMessage:消息的主体为二进制数据。13. Weblogic Server中的JMS配置l 创建持久存储在Weblogic中可以选择创建文件方式和数据库方式的持久存储。下面创建一个文件方式的持久存储。依次展开到Services/JMS/Stores节点,并点击Stroes。点击Configure a new JMS File Store.超连接。这里只需要修改存储消息的文件路径就可以了(注意此路径必须实际存在),如我的输入的是:C:beauser_projectsdomainstestdomainjmsfile,名字我们可以采用默认的。点击Create,文件存储创建完成。l 配置JMS服务器所有的JMS管理对象,包括JMS队列、主题都位于特定的JMS服务器。单击JMS下的Servers节点。然后点击超连接Configure a new JMS Server.。首先填写服务器的名字,Persistent Store选择刚才创建的持久存储的名称。然后点击Create。然后选择我们要部署的服务器。点击Apply。l 创建JMS连接工厂点击JMS下的Connection Factories。然后点击超连接。这里名字可以不改,输入JNDI的名字:TestJMSFactory。点击Create,然后不要忘记部署到服务器上。l 配置JMS目的:队列和主题单击新建的JMS Server节点(本例中是:MyJMS Server)下的Destinations项,可以看到两个连接。单击Configure a new JMS Queue.,这里我们输入队列的JNDI名,MyTestJMSQueue,Eable Store选项选择true。单击Create按钮。下面我们在创建一个主题。在目的的页面点击Configure a new JMS Topic.连接。在JNDI输入MyTestJMSTopic。其他不用变,单击Create,主题创建完成。二 在完成上面的配置后,我们重新启动Weblogic服务,开始JMS开发实例1 在E盘上创建jmstest文件夹。2 创建工程MyJMS。路径选择刚才创建的文件夹。3 单击新建,选择JMS。点击OK。然后选择服务器。4 搜索在此输入类名。主要这里我们选择点对点方式。点击Next在这里我们输入刚才创建的消息工厂和消息队列的JNDI名。点击Finish。此时可以看到JBuilder为我们生成的创建封装JMS调用的JMS类,并修改。修改的代码(配置环境修改的代码略,这里我们将收到的信息放到一个文件中,因此添加了一个方法。)如下: public void onMessage(Message message) if (message instanceof javax.jms.BytesMessage) javax.jms.BytesMessage bytesMessage = (javax.jms.BytesMessage) message; /* todo Process bytesMessage here */ else if (message instanceof javax.jms.MapMessage) javax.jms.MapMessage mapMessage = (javax.jms.MapMessage) message; /* todo Process mapMessage here */ else if (message instanceof javax.jms.ObjectMessage) javax.jms.ObjectMessage objectMessage = (javax.jms.ObjectMessage) message; /* todo Process objectMessage here */ else if (message instanceof javax.jms.StreamMessage) javax.jms.StreamMessage streamMessage = (javax.jms.StreamMessage) message; /* todo Process streamMessage here */ else if (message instanceof javax.jms.TextMessage) javax.jms.TextMessage objectMessage = (javax.jms.TextMessage) message; try printReceiverMessage(收到的消息为: + objectMessage.getText(); catch (JMSException ex1) ex1.printStackTrace(); if (isTransacted() try getQueueSession().commit(); catch (Exception ex) ex.printStackTrace(); public void printReceiverMessage(String s) BufferedWriter bufferedwriter = null; FileOutputStream fileoutputstream = null; String messageFileName = e:+File.separator+jmstest+File.separator+jmsreceiver; if (messageFileName = null) return; try String sTemp = messageFileName.substring(0, messageFileName.lastIndexOf(File.separator); File file = new File(sTemp); if (!file.exists() file.mkdirs(); catch (Exception ex3) ex3.printStackTrace(); try fileoutputstream = new FileOutputStream(messageFileName, true); catch (FileNotFoundException ex1) ex1.printStackTrace(); bufferedwriter = new BufferedWriter(new OutputStreamWriter( fileoutputstream); try bufferedwriter.newLine(); if (s = null) return; Date today = new Date(); DateFormat datetime = DateFormat.getDateTimeInstance(); bufferedwriter.write(datetime.format(today); bufferedwriter.newLine(); if (s.equals(newLine) bufferedwriter.newLine(); else bufferedwriter.write(s); catch (IOException ex) ex.printStackTrace(); try bufferedwriter.close(); catch (IOException ex2) finally try bufferedwriter.close(); catch (IOException ex4) 下面我们创建消息生产者,该类是一个普通类。package jmstest;/* * Title: * Description: * Copyright: Copyright (c) 2005 * Company: dvt * author ljc * version 1.0 */public class MessageCreater public MessageCreater() public static void main(String args) MessageCreater messageCreater1 = new MessageCreater(); PTPJMSTest test = new PTPJMSTest(); String message = Message creator test!; try / for(int i=0;i1000;i+)/ test.sendText(message);/ test.close(); catch (Exception ex) ex.printStackTrace(); 创建消息消费者,该类也是一个普通类package jmstest;/* * Title: * Description: * Copyright: Copyright (c) 2005 * Company: dvt * author ljc * version 1.0 */public class MessageReceiver public MessageReceiver() public static void main(String args) MessageReceiver messageReceiver1 = new MessageReceiver(); PTPJMSTest test = new PTPJMSTest(); try test.getQueueReceiver(); System.out.println(waiting for message); synchronized(test) test.wait(100000); catch (Exception ex) ex.printStackTrace(); 现在程序开发完成了,我们可以测试了。运行消息发送者,然后运行消息接受者,然后打开文件,可以看到我们发送的消息已经写到文件中了。作业:我们联系是点对点消息发送,我们课后练习订阅发布消息发送。第十二章一驱动Bean是异步消息的消费者,当JMS目的(队列或主题)接受到消息时,EJB容器调用消息驱动Bean,消息驱动Bean没有Home接口和组件接口。消息驱动Bean中有一个onMessage方法,当有消息到达时,EJB容器会自动调用该方法,所有可以把消息驱动Bean的处理代码放到该方法中。二消息驱动Bean和JMS客户机的区别这部分取决于在应用程序需求环境中有多少控制,同时还取决于需要编写多少代码。如果需要很好的控制JMS基础结构、事务和数据访问,那么客户机比较适合你。但是如果只是简单的编写执行相对简单进程的队列监听器和主题预定者,就应该考虑是否应该使用消息驱动Bean。使用消息驱动Bean,可以从EJB容器对管理JMS基础结构、控制事务、强制安全性和管理数据库的显式支持中受益。也可以通过部署描述符在运行时对消息队列等做一些改动。下面给出一个表用来说出他们的区别特性消息驱动BeanJMS客户机事务支持容器管理由开发人员编码绑定只可绑定到一个JMS主题和队列可以绑定到任何数目的JMS主题或队列JMS基础结构管理由容器管理由开发人员管理运行时JMS行为由部署描述符控制由代码和Weblogic控制台设置控制三 消息驱动Bean的生命周期消息驱动Bean的生命周期非常类似于无状态会话Bean。1 当EJB容器调用消息驱动Bean类的newInstance方法创建一个实例时,一个消息驱动Bean的生命周期就开始了。2 EJB容器调用setMessageDriventContext方法。3 调用ejbCreate方法。4 消息驱动Bean准备处理发送到目的(队列或主题)的消息,直到超期。5 当EJB容器不再需要消息驱动Bean的实例时,EJB容器就调用ejbRemove方法,这就结束消息驱动Bean实例的生命周期。四 消息驱动bean实例 在E盘上创建文件夹mdb。创建工程:mymdb,服务器选择Weblogic创建EJB Module:EJBModule1创建消息驱动bean:TestMDB在此窗口中我们分别输入MDB的名字,这里我们测试发布订阅消息,然后输入目的名字和连接工厂的名字。这里我们修改事务类型,将部署描述符ejb-jar.xml EJBModule1 TestMDB mymdb.TestMDBBean Container javax.jms.Topic Durable TestMDB * NotSupported 修改MDB代码。package mymdb;import java.io.*;import java.text.DateFormat;import java.util.Date;import javax.ejb.*;import javax.jms.Message;import javax.jms.MessageListener;public class TestMDBBean implements MessageDrivenBean, MessageListener MessageDrivenContext messageDrivenContext; public void ejbCreate() throws CreateException public void ejbRemove() public void onMessage(Message message) javax.jms.TextMessage objectMessage = (javax.jms.TextMessage) message; try printReceiverMessage(收到的消息为: + objectMessage.getText(); catch (Exception ex1) ex1.printStackTrace(); public void printReceiverMessage(String s) BufferedWriter bufferedwriter = null; FileOutputStream fileoutputstream = null; String messageFileName = e: + File.separator + mdb + File.separator + jmsreceiver; if (messageFileName = null) return; try String sTemp = messageFileName.substring(0, messageFileName.lastIndexOf(File.separator); File file = new File(sTemp); if (!file.exists() file.mkdirs(); catch (Exception ex3) ex3.printStackTrace(); try fileoutputstream = new FileOutputStream(messageFileName, true); catch (FileNotFoundException ex1) ex1.printStackTrace(); bufferedwriter = new BufferedWriter(new OutputStreamWriter( fileoutputstream); try bufferedwriter.newLine(); if (s = null) return; Date today = new Date(); DateFormat datetime = DateFormat.getDateTimeInstance(); bufferedwriter.write(datetime.format(today); bufferedwriter.newLine(); if (s.equals(newLine) bufferedwriter.newLine(); else bufferedwriter.write(s); catch (IOException ex) ex.printStackTrace(); try bufferedwriter.close(); catch (IOException ex2) finally try bufferedwriter.close(); catch (IOException ex4) public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) this.messageDrivenContext = messageDrivenContext; 现在可以编译部署我们的应用程序了。然后我们再按照上节课的方法创建消息发布者。就可以测试应用程序了。第十三章通过本节课总结三种EJB的特点和生命周期一 EJB的生存周期企业Bean的生命周期可以划分为几个阶段,不过不同类型的企业Bean如会话Bean,EntityBean和Message-DrivenBean都有不同的生命周期。 1有状态会话Bean的生命周期: 下图显示了一个有状态会话Bean的生命周期中的三个阶段:从不存在到准备就绪到钝化,然后原路返回。客户端调用create方法(该方法在Home或者Local Home节口中声明)就开始了一个有状态会话Bean的生命周期(在此之前是Does Not Exist,不存在阶段)。EJB容器产生一个Bean的实例然后调用Bean类的setSessionContext和ejbCreate(和Home或者Local Home节口中被调用的create方法对应的ejbCreate)方法。这时该Bean实例进入准备就绪状态(Ready),它的商业方法可以被客户端调用了。在就绪状态,EJB容器可能会把该Bean实例从内存中移出到外存以钝化该实例(EJB容器一般采用最近最少使用原则来钝化内存中的Bean实例)。其实就是把内存中EJB容器认为暂时不会用到的Bean实例转移到外存中,以提高内存使用效率,这好像是支持多线程操作系统的内存管理。在钝化Bean实例之前,EJB容器会先调用ejbPassivate方法,所以你如果想在钝化之前做什么动作的话就可以在该方法里实现。如果钝化期间有客户端调用该Bean实例的商业方法,EJB容器将该实例读入内存激活它回到就绪组状态(很有点线程的状态变化哦),同时调用该Bean类的ejbActivate方法。所以你要在Bean实例被激活的时候做点什么动作的话,就在这个方法里动点手脚就OK了:)。在企业Bean的生命周期最后,客户端调用remove(同样是Home或者Local Home接口里的)方法然后容器调用Bean类的ejbRemove方法结束了一个实例的生命。该实例就乖乖的等待垃圾收集器的召唤了。在这些生命周期方法中,你可以在客户端编码调用的只有两个:create和remove方法,如图所示的其他方法都是由EJB容器来调用的。例如,ejbCreate方法在Bean类里,允许你在Bean类实例化后执行一些特定的操作,比如你想让它自己实例化后就报个到,喊一声“我来了”,那把代码塞在这个方法里面就没错了。或者你是想让它跟要访问的数据库打个招呼,建个连接也在这里。2无状态会话Bean的生命周期因为无状态会话Bean不需要保存任何状态信息,所以它不需要钝化,在不用的时候直接干掉就好了。所以它的生命周期只有两个阶段:不存在(Does Not Exist)和就绪(Ready)如下图 3EntityBean的生命周期图3-5显示了EntityBean生命周期中的三个阶段:不存在、池状态和就绪。EJB容器创建企业Bean实例后调用它的setEntityContext方法,该方法将实体上下文(Entity Context)传递给Bean实例。然后该实例就被放入同类实例的Bean池中。在这个状态中,实例并没有和特定的EJB对象身份标志关联,池中所有实例都是等价的。EJB容器在把实例变为就绪状态时才为它指定一个特定的标志。(实体Bean映射商业实体,具有分辨实体的唯一主键标志) 有两种方法让实例从池状态到就绪状态。第一种方法,客户端调用create方法,然后EJB容器调用ejbCreate和ejbPostCreate方法。第二种方法,EJB容器调用ejbActive方法。只用在就绪状态下,企业Bean才可以为客户端提供服务。 在EntityBean的生命周期的最后,EJB容器从池中删除Bean实例并调用unsetEntityContext方法。 企业Bean实例在Bean池中并不和任何EJB实体标志关联。以BMP为例,在EJB容器把实例从池状态转到就绪状态时,它并不自动设置实例的主键,所以ejbCreate和ejbActivate方法必须对主键赋值。如果主键不正确,ejbLoad和ejbStore方法(这两个方法在实体Bean种执行和数据库同步数据操作,在BMP中要自己编码实现,BMP一章将详细介绍)就不能正确的在Bean字段和数据库数据之间执行同步。在SavingAccountEJB的例子中,ejbCreate方法通过自身的参数对主键赋值。EjbActivate方法用下面的语句对主键(id)赋值:id = (String)context.getPrimaryKey();在池状态下,企业Bean的字段的值是不需要的,你可以在ejbPassivate方法里把这些值置空(赋值为null)一边垃圾收集器可以收集它们。4Message-DrivenBean的生命周期图3-6显示了Message-DrivenBean生命周期中的两个阶段:不存在和就绪。EJB容器通常会创建一个Message-DrivenBean的实例池。对其中每一个实例EJB容器完成如下工作:1. 调用setMessageDrivenContext方法传递上下文对象给实例。2. 调用ejbCreate方法和无状态会话Bean一样,Message-DrivenBean也不会被钝化,只有两种状态:不存在和就绪(可以接收消息)。在生命周期的最后容器调用ejbRemove方法,实例就开始等

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论