1 / 52

EJB3.0 企业开发

EJB3.0 企业开发. 讲师:黎活明. 什么是 EJB. Enterprise JavaBeans 是一个用于分布式业务应用的标准服务端组件模型。采用 Enterprise JavaBeans 架构编写的应用是可伸缩的、事务性的、多用户安全的。采用 ejb 编写的这些应用,可以部署在任何支持 Enterprise JavaBeans 规范的服务器平台,如 jboss 、 weblogic 等。. EJB 用来干什么 ?.

snana
Download Presentation

EJB3.0 企业开发

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. EJB3.0企业开发 讲师:黎活明 北京传智播客教育 www.itcast.cn

  2. 什么是EJB Enterprise JavaBeans是一个用于分布式业务应用的标准服务端组件模型。采用Enterprise JavaBeans架构编写的应用是可伸缩的、事务性的、多用户安全的。采用ejb编写的这些应用,可以部署在任何支持Enterprise JavaBeans规范的服务器平台,如jboss、weblogic等。 北京传智播客教育 www.itcast.cn

  3. EJB用来干什么? EJB实际上是用于编写业务层代码。如果大家对于MVC (model-view-controller)结构的应用有所了解的话,我们知道一个基于MVC结构的应用应包含显示层、控制层和业务层, 假设我们采用ejb开发基于MVC结构的应用,那么ejb就是用于开发应用的业务层. 北京传智播客教育 www.itcast.cn

  4. EJB的好处 EJB为我们提供了很多在企业开发中需要使用到的服务,如事务管理/安全/持久化/分布式等,因为这些服务由容器提供,无需我们自行开发,这样大大减少了我们的开发工作量.另外EJB提供了强制式分层解耦设计方法 北京传智播客教育 www.itcast.cn

  5. EJB3VS Spring2.5 估计有同学会问,除了EJB,像spring+hibernate同样提供了事务管理/持久化服务,好像没有必要使用ejb. 如果你的应用不需要分布式能力,确实没有必要使用ejb, 因为spring+hibernate提供了大部分原来只有ejb才有的服务,而且spring提供的有些服务比ejb做的更细致,更周到。那么是不是有了spring,EJB3就没有必要存在了?这种说法是不正确的,因为ejb设计的初衷是用于分布式场合,而spring一开始就没有打算提供分布式功能。所以两者看似有竞争的关系,但实际上两者的偏重点不一样,像ejb比较适合用于大型企业,因为大型企业一般都会存在多个信息系统,而这些信息系统又相互关联。为了避免业务功能重复开发,实现最大程度的重用,有必要把业务层独立出来,让多个信息系统共享一个业务中心,这样应用就需要具备分布式能力。 北京传智播客教育 www.itcast.cn

  6. EJB3 的分布式特点 北京传智播客教育 www.itcast.cn

  7. EJB3 的分布式特点 北京传智播客教育 www.itcast.cn

  8. 我是否应该学习EJB3? 经常有同学会问我要不要学习ejb3?如果你学习ejb3只为了找份工作的话,那么我告诉你一个现实情况, 目前使用ejb3的人数虽然有所上升,但是在关于ejb3的工作岗位并不多。所以依靠它找工作的话,恐怕会让你失望。当然如果你只是为了学习的话,那么ejb3是非常值我们学习的,因为ejb3包含的知识点非常多,学习它可以开拓我们的知识面。对于一线的java开发人员,我更是建议,不管在工作中是否用到ejb3,都应该学习一下ejb3,因为通过学习她,可以让你站在更高的台阶思考问题。 北京传智播客教育 www.itcast.cn

  9. EJB的发展前景 很多人都会问到ejb的发展前景,可以告诉大家ejb的发展前景会越来越好。目前在java社区关于ejb讨论的话题并不是很多,而且ejb占领的市场份额也很少,这种情况主要与它的定位有关,至少现在它的定位还是在分布式应用。有组织统计过在100个项目中,需要分布式的应用只占15%,而85%的应用都是不需要分布式的,这个比例就决定了关注ejb的人不会很多,而且ejb所占的市场份额也不会很大。如果ejb要占领大部分市场份额就必须提供像Spring这样的轻量级解决方案。好在ejb专家组已经认识到了这一点,目前正计划在ejb3.1规范中加入轻量级解决方案(ejb3.1可能会分成两个版本,一个仍然定位于分布式应用,另一个定位于轻量级应用)。如果这个计划得以实现的话,恐怕到时ejb3.1将会逐步吞食由Spring占领的市场份额。因为ejb3的开发和spring一样的简单,而且ejb3是javaee5规范里的技术,所以大部分项目经理都愿意选择一种开发简单、又被更多厂商兼容的标准技术。 北京传智播客教育 www.itcast.cn

  10. EJB3.0的学习资源 • 《EJB3.0入门经典》出版书,网上卖价:45元 购买地址: http://www.china-pub.com/41146 • 《EJB3.0实例教程》免费电子版 下载地址:http://www.foshanshop.net 北京传智播客教育 www.itcast.cn

  11. EJB3的运行环境 EJB3.0应用需要运行在JDK1.5以上版本。 进入http://java.sun.com/javase/downloads/index_jdk5.jsp下载JDK。在页面中找到JDK 5.0 Update 16(版本在不断更新中,有可能大于16),点击右边的Download。 按照安装向导提示安装,安装路径选择C:\Java\jdk1.5.0_16。Jdk安装完后,接着问你是否安装jre,也一起安装上。 右键点击“我的电脑”->“属性”->“高级”->“环境变量”,在“系统变量”里添加JAVA_HOME 变量,值为JDK的安装路径,如:C:\ Java\jdk1.5.0_16。 在“系统变量”里再添加CLASSPATH变量,值为:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; 在系统变量栏找到变量名为Path的选项,点“编辑”在变量值的末尾添加;%JAVA_HOME%\bin; 北京传智播客教育 www.itcast.cn

  12. EJB3的运行环境 EJB3.0应用需要运行在EJB容器里,下面是一些JavaEE应用服务器,JavaEE应用服务器包含Web容器和EJB容器。 • Jboss(4.2.x以上版本) 是一个成熟的开源的准JavaEE应用服务器,在开源JavaEE应用服务器中所占市场份额第一。如果你打算选用开源的JavaEE应用服务器,那么jboss是最值得选择的。 • Glassfish 是一个开源的JavaEE应用服务器,对JavaEE规范的支持非常好,其运行性能比较高。因为发展时间相对较短,市场占有率比较低。另外,它能否提供稳定的运行性能,还有待时间的考验。但本人对其后期的发展非常看好。绝对跟jboss有的一拼。 • Weblogic(10以上版本) 是商业市场占有率第一的商业JavaEE应用服务器,它具有出色的稳定性,并提供了人性化的管理界面,还有企业需要使用到的众多功能。但在ejb3.0领域,本人认为它做的比jboss差些,bug比较多。 • Sun Application Server(9.0以上版本) 商业JavaEE应用服务器,如果你打算选用商业应用服务器运行ejb3,这个是不错的选择。 • Oracle Application Server(10g以上版本) 商业JavaEE应用服务器,如果你的数据库是oracle,要想兼容性更好,这个是不错的选择。 • apusic应用服务器 这是国内的商业JavaEE应用服务器,主要在政府中占有一定的市场份额。要批评的是,其向开发人员提供的文档实在太少了,本人曾经想在其上面开发应用,结果找了大半天也没有找到需要的开发文档。 注意:Tomcat目前只是Web容器,它不能运行EJB应用。 北京传智播客教育 www.itcast.cn

  13. 进入http://labs.jboss.com/jbossas/downloads/下载页面,选择jboss4.2.3.GA下载(大小为95MB),如果你安装的jdk是1.5版本,请选择jboss-4.2.3.GA.zip 文件下载。 如果你安装的jdk是1.6版本,请选择jboss-4.2.3.GA-jdk6.zip 文件下载。下载后直接解压缩文件即可完成安装,为了避免应用出现莫名的错误,解压缩的路径最好不要带有空格和中文,如“Program Files”。 下载与安装jboss 北京传智播客教育 www.itcast.cn

  14. 进入jboss的bin目录,找到启动脚本run.bat 。双击run.bat即可启动jboss,此时启动的配置项为default。 如果启动出错,请检查下列情况: 1.端口是否被占用,如:8080、1099 2是否为JDK设置的JAVA_HOME和ClassPath系统变量,如果没有,请按照前面视频介绍的方法设置。 3.检查jboss所用的jdk是否1.5以上版本,这些信息可以在jboss的控制台观察到。 4.如果启动时出现这样的错误:“findstr不是内部或外部命令,也不是可运行的程序或批处理文件”。那么应该在系统变量Path中追加“%SystemRoot%\system32;%SystemRoot%;”。 最后的办法是重装机器上的JDK,祝你好运。 启动JBoss 北京传智播客教育 www.itcast.cn

  15. 因为在后面的学习中,我们需要使用到系统变量JBOSS_HOME,它指向jboss的安装路径。所以安装完后我们需要添加该变量,方法是:右键点击“我的电脑”->“属性”->“高级”->“环境变量”,在“系统变量”里添加JBOSS_HOME变量,值为Jboss的安装路径,如:D:\JavaEEServer\jboss。因为在后面的学习中,我们需要使用到系统变量JBOSS_HOME,它指向jboss的安装路径。所以安装完后我们需要添加该变量,方法是:右键点击“我的电脑”->“属性”->“高级”->“环境变量”,在“系统变量”里添加JBOSS_HOME变量,值为Jboss的安装路径,如:D:\JavaEEServer\jboss。 为了方便输入jboss的命令,我们把jboss的bin目录添加到系统路径里。在系统变量一栏找到变量名为Path的选项,点“编辑”在变量值的末尾添加:;%JBOSS_HOME%\bin; 为jboss设置JBOSS_HOME系统变量 北京传智播客教育 www.itcast.cn

  16. EJB中的三种bean 1.会话bean(session bean) 负责与客户端交互,是编写业务逻辑的地方,在会话bean中可以通过jdbc直接操作数据库,但大多数情况下都是通过实体bean来完成对数据库的操作. 2.实体bean(entity bean) 它实际上属于java持久化规范(简称JPA)里的技术, JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink等ORM框架各自为营的局面。 3.消息驱动bean(message-driven bean) 它是专门用于异步处理java消息的组件.具有处理大量并发消息的能力. 北京传智播客教育 www.itcast.cn

  17. 会话bean • 无状态会话bean • 平常,我们使用最多的是无状态bean,因为它的bean实例可供多个用户使用,所以它的性能比有状态bean高.正因为一个bean实例被多个用户使用.那么,前一个用户设置的值有可能被后一个用户所修改,所以它无法正确保存某个用户设置的值,因此是无状态的. • 有状态会话bean • 有状态bean平常使用的并不多,因为它的一个bean实例只供一个用户使用,所以性能开销比较大,正因为它的实例只被一个用户使用, 用户为它设置的值是不会被其他用户修改,所以可以正确保存用户设置的值,因此是有状态的. 北京传智播客教育 www.itcast.cn

  18. 如何开发一个无状态会话bean • 开发工具: Eclipse IDE for Java EE • 下载地址:http://www.eclipse.org/downloads • 开发EJB依赖的jar文件 • 可以在jboss安装路径的client目录下找到,通常会把client目录下的所有jar文件添加到项目的类路径下. 北京传智播客教育 www.itcast.cn

  19. 如何开发一个无状态会话bean • 接口(接口可以是远程接口或本地接口) • 实现类 北京传智播客教育 www.itcast.cn

  20. Session bean的客户端开发 public static void main(String[] args) { Properties props = new Properties(); props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); props.setProperty("java.naming.provider.url", "localhost:1099"); try { InitialContext ctx = new InitialContext(props); HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote"); System.out.println(helloworld.sayHello("佛山")); } catch (NamingException e) { System.out.println(e.getMessage()); } } 北京传智播客教育 www.itcast.cn

  21. 设置JNDI访问环境信息 在进行JNDI查找前,我们必须设置应用服务器的上下文信息,主要是设置JNDI驱动的类名(java.naming.factory.initial)和命名服务提供者的URL (java.naming.provider.url) 。 • java.naming.factory.initial或Context.INITIAL_CONTEXT_FACTORY:环境属性名,用于指定InitialContext工厂(作者称它为JNDI驱动更容易理解),它类似于JDBC指定数据库驱动类。 因为本例子连接的是JbossNS(命名服务的实现者),所以使用Jboss提供的驱动类:org.jnp.interfaces.NamingContextFactory • java.naming.provider.url或Context.PROVIDER_URL:环境属性名,包含提供命名服务的主机地址和端口号。它类似于JDBC指定数据库的连接URL。连接到JbossNS的URL格式为:jnp://host:port,该URL的“jnp:”部分是指使用的协议,JBoss使用的是基于Socket/RMI的协议。host为主机的地址,port为JNDI服务的端口。除了host之外,其他部分都是可以不写的。 下面是数据库访问例子: Class.forName("org.gjt.mm.mysql.Driver").newInstance(); Properties props = new Properties(); props.put("user","root"); props.put("password","123456"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/itcast", props); 北京传智播客教育 www.itcast.cn

  22. 设置JNDI访问环境信息 如同数据库一样,根据访问命名服务器的不同,为上下文设置的驱动类和URL也是不同的,如下面是访问Sun应用服务器的上下文信息: Properties props = new Properties(); props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory"); props.setProperty("java.naming.provider.url", "localhost:3700"); InitialContext = new InitialContext(props); HelloWorld helloworld = (HelloWorld) ctx.lookup("com.foshanshop.ejb3.HelloWorld"); 如果客户端运行在应用服务器内,我们不需要为InitialContext设置应用服务器的上下文信息,也不建议设置。因为应用服务器启动时会把JNDI驱动类等上下文信息添加进系统属性,创建InitialContext对象时如果没有指定Properties参数,InitialContext内部会调用System.getProperty()方法从系统属性里获取必要的上下文信息。对本例子而言,你可以省略传入props参数,之所以给InitialContext设置参数,目的是引出相关知识点,便于教学。在实际应用中,如果给InitialContext设置了参数,反而会带来不可移植的问题。 注:创建InitialContext对象时如果没有指定Properties参数,InitialContext还会在classpath下寻找jndi.properties文件,并从该文件中加载应用服务器的上下文信息。这样避免了硬编码为InitialContext设置Properties参数。 jndi.properties的配置如下: java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces 北京传智播客教育 www.itcast.cn

  23. Jboss默认生成的JNDI 名称 当EJB发布到Jboss 时,如果我们没有为它指定全局JNDI名称或修改过其默认EJB名称,Jboss就会按照默认的命名规则为EJB生成全局JNDI名称,默认的命名规则如下: 如果把EJB作为模块打包进后缀为*.ear的JAVA EE企业应用文件,默认的全局JNDI名称是 • 本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local • 远程接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote EAR-FILE-BASE-NAME为ear文件的名称,EJB-CLASS-NAME为EJB的非限定类名。 例:把HelloWorld应用作为EJB模块打包进名为HelloWorld.ear的企业应用文件,它的远程接口的JNDI 名称是:HelloWorld/HelloWorldBean/remote 如果把EJB应用打包成后缀为*.jar的模块文件,默认的全局JNDI名称是 • 本地接口:EJB-CLASS-NAME/local • 远程接口:EJB-CLASS-NAME/remote 例:把HelloWorld应用打包成HelloWorld.jar文件,它的远程接口的JNDI名称是:HelloWorldBean/remote 北京传智播客教育 www.itcast.cn

  24. 使用注释改变Session Bean的JNDI 名称 如果我们没有指定EJB的JNDI名称,当EJB发布到应用服务器时,应用服务器会按默认规则为EJB生成全局JNDI名称。当我们需要自定义JNDI名称时,可以这样做 如果EJB在Jboss中使用,可以使用Jboss提供的 @LocalBinding 和 @RemoteBinding 注释,@LocalBinding注释指定Session Bean的Local接口的JNDI名称,@RemoteBinding注释指定Session Bean的Remote接口的JNDI名称,如下: @Stateless @Remote ({Operation.class}) @RemoteBinding (jndiBinding="foshanshop/RemoteOperation") @Local ({LocalOperation.class}) @LocalBinding (jndiBinding="foshanshop/LocalOperation") public class OperationBean implements Operation, LocalOperation { } 北京传智播客教育 www.itcast.cn

  25. 使用xml部署描述文件改变Session Bean的JNDI 名称 由于JNDI名称与厂商有关,如果使用注释定义JNDI名称会带来移植问题,因此建议使用ejb-jar.xml部署描述文件进行定义,该文件必须放置在jar的META-INF目录下 <?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns=http://java.sun.com/xml/ns/javaeexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"> <enterprise-beans> <session> <ejb-name>HelloWorldBean</ejb-name> <mapped-name>HelloWorldBean</mapped-name> </session> </enterprise-beans> </ejb-jar> ejb-name为EJB名称,mapped-name为bean的JNDI名称。目前jboss不支持在ejb-jar.xml通过mapped-name指定JNDI名称,但我们可以使用他专属的部署描述文件jboss.xml进行定义,如下: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.2//EN“ "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd"> <jboss> <enterprise-beans> <session> <ejb-name>HelloWorldBean</ejb-name> <jndi-name>hello/remote</jndi-name> </session></enterprise-beans></jboss> 北京传智播客教育 www.itcast.cn

  26. 开发具有Local接口的Session bean 之前,我们介绍过远程接口,在这里,我们需要了解一下通过远程接口调用ejb的过程,首先客户端需要与ejb建立起socket通信,在通信管道上他们之间需要来回发送IIOP协议消息,因为数据要在网络进行传输,存放数据的java对象必须要进行序列化。 socket通信 IIOP消息 在这个过程中我们看到,有网络通信的开销、协议解析的开销、对象序列化的开销。因为ejb是分布式技术,它允许客户端与ejb应用在不同一机器上面,所以这些性能开销也是必然的。但是在实际生产中,不可避免存在这种情况:客户端与EJB应用运行在同一个jboss中。这时候客户端访问ejb是否有必要走上面的网络通信呢?据我们所知,这时候客户端与ejb是在同一个jvm内,他们之间完全可以通过内存进行交互,这样就可以避免网络通信的性能开销。既然我们都想到了这一点,EJB专家组也想到了这一点,所以引入了本地接口。通过本地接口调用ejb,直接在内存中交互,这样就能避免因网络通信所造成的各种性能开销。但是有一点,大家必须注意,只有客户端与EJB应用在同一个JVM内运行的时候,我们才能调用本地接口,否则只能调用远程接口。谈到这里,有同学会问什么情况下客户端与EJB应用是在同一个JVM?简单地说只要客户端与ejb发布在同一个jboss内,我们就认为他们是在同一个JVM EJB 客户端 北京传智播客教育 www.itcast.cn

  27. 开发具有local接口session bean @Stateless @Local ({HelloWorldLocal.class}) public class HelloWorldBean implements HelloWorldLocal { public String say (String name) { return name +"说:你好!世界,这是我的第一个EJB3哦."; } } 北京传智播客教育 www.itcast.cn

  28. 通过local接口访问session bean <%@ page import="cn.itcast.ejb3.HelloWorldLocal, javax.naming.*, java.util.Properties"%> <% try { InitialContext ctx = new InitialContext(); HelloWorldLocal helloworld = (HelloWorldLocal) ctx.lookup("HelloWorldBean/local"); out.println(helloworld.sayHello("佛山人")); } catch (NamingException e) { out.println(e.getMessage()); } %> 北京传智播客教育 www.itcast.cn

  29. Bean实例的两种管理技术 1.无状态bean使用实例池技术管理bean 2.有状态bean使用激活(activation)管理bean 北京传智播客教育 www.itcast.cn

  30. 无状态bean访问 是1号用户 指另一个用户 北京传智播客教育 www.itcast.cn

  31. 有状态bean的激活机制 每个用户都有自己的Bean实例,相当于有多少个用户就有多少个Bean实例为之服务。如果不采取任何机制,这样必然会导致服务器资源严重消耗,最后落个down机罢工。为了解决这个问题,EJB引入了激活机制。该机制实现的原理是这样的,在EJB服务器需要节省资源时,就从内存中收回bean实例,将其所保持的会话状态序列化到硬盘中,并且释放其所占有的内存。若此时客户端对EJB再次发起请求,EJB容器会重新实例化一个Bean实例,并从硬盘中将之前的状态恢复。 北京传智播客教育 www.itcast.cn

  32. EJB调用机制 由于EJB的调用过程对开发者来说是透明的,以至于我们错误地认为:lookup()方法返回的对象就是bean实例。实际上,客户端与Session bean交互,它并不直接与Bean实例打交道,而是经由bean的远程或本地接口。当你调用远程或本地接口的方法时,接口使用的是存根(stub)对象。该存根实现了session bean的远程或本地接口。它负责将方法调用经过网络发送到远程EJB容器,或将请求路由到位于本地JVM内的EJB容器。存根是在部署期间使用JDK所带的java.lang.reflect.Proxy动态生成。 北京传智播客教育 www.itcast.cn

  33. EJB调用机制 第一步:客户端调用远程接口的SayHello()方法(实际上调用的是存根对象的SayHello()方法,该存根实现了HelloWorld的远程接口)。 第二步:方法调用经过IIOP Runtime被转换成CORBA IIOP消息发往应用服务器。 第三步:应用服务器接收到请求消息后,交由骨架(skeleton)处理。骨架通过IIOP Runtime解析协议消息,并根据协议要求调用bean实例的SayHello()方法。 第四步:骨架(skeleton)将SayHello()方法的返回值经过IIOP Runtime转换成CORBA IIOP应答消息发回客户端。 第五步:存根对象通过IIOP Runtime将CORBA IIOP应答消息解析成返回值。 北京传智播客教育 www.itcast.cn

  34. 依赖注入(dependency injection) 注入ejb: @Stateless @Remote (Injection.class) publicclass InjectionBean implements Injection { @EJB (beanName="HelloBean") LocalHello helloworld; public String SayHello() { return helloworld.SayHello("注入者"); } } 北京传智播客教育 www.itcast.cn

  35. 依赖注入(dependency injection) 注入数据源: @Resource(mappedName = "java:/DefaultMySqlDS") DataSource myDb; Connection conn = null; try { conn = myDb.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT studentName FROM student"); if (rs.next()) str = rs.getString(1); rs.close(); stmt.close(); } catch (SQLException e) { e.printStackTrace(); }finally{ try { if(null!=conn && !conn.isClosed()) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } 北京传智播客教育 www.itcast.cn

  36. 在jboss中配置数据源 <?xml version="1.0" encoding="UTF-8"?> <datasources> <local-tx-datasource> <jndi-name>DefaultMySqlDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/itcast?useUnicode=true&amp;characterEncoding=UTF-8</connection-url> <driver-class>org.gjt.mm.mysql.Driver</driver-class> <user-name>root</user-name> <password>123456</password> <min-pool-size>3</min-pool-size> <max-pool-size>100</max-pool-size> <!-- TRANSACTION_READ_UNCOMMITTED TRANSACTION_READ_COMMITTED TRANSACTION_REPEATABLE_READ TRANSACTION_SERIALIZABLE <transaction-isolation>TRANSACTION_SERIALIZABLE</transaction-isolation>--> <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name> <metadata> <type-mapping>mySQL</type-mapping> </metadata> </local-tx-datasource> </datasources> 北京传智播客教育 www.itcast.cn

  37. 实体bean 它属于java持久化规范(简称JPA)里的技术,实体bean通过元数据在javabean和数据库表之间建立起映射关系,然后Java程序员就可以随心所欲的使用面向对象的编程思想来操纵数据库。 JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,目前实现的JPA规范的主流产品有Hibernate、TopLink和OpenJPA,在jboss中采用了Hibernate 作为其持久化实现产品。 北京传智播客教育 www.itcast.cn

  38. 添加JPA的配置文件persistence.xml 根据JPA规范的要求:在实体bean应用中,我们需要在应用的类路径下的META-INF目录加入持久化配置文件persistence.xml <?xml version="1.0"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> </persistence> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> <!-- 显示最终执行的SQL --> <property name="hibernate.show_sql" value="true"/> <!-- 格式化显示的SQL --> <property name="hibernate.format_sql" value="true"/> 北京传智播客教育 www.itcast.cn

  39. 实体bean 当插入中文字符时会报: Data too long for column。你可以使用下面的SQL创建数据库: create database `foshanshop` DEFAULT CHARSET=utf8 北京传智播客教育 www.itcast.cn

  40. Java消息服务(Java Message Service) Java 消息服务(Java Message Service,简称 JMS)是用于访问企业消息系统的开发商中立的API。企业消息系统可以协助应用软件通过网络进行消息交互。 JMS的编程过程很简单,概括为:应用程序A发送一条消息到消息服务器的某个目得地(Destination),然后消息服务器把消息转发给应用程序B。因为应用程序A和应用程序B没有直接的代码关连,所以两者实现了解偶。如下图: 北京传智播客教育 www.itcast.cn

  41. JMS中的消息 消息传递系统的中心就是消息。一条 Message 由三个部分组成: 头(header),属性(property)和主体(body)。 消息有下面几种类型,他们都是派生自 Message 接口。 StreamMessage:一种主体中包含 Java 基元值流的消息。其填充和读取均按顺序进行。 MapMessage:一种主体中包含一组名-值对的消息。没有定义条目顺序。 TextMessage:一种主体中包含 Java 字符串的消息(例如,XML 消息)。 ObjectMessage:一种主体中包含序列化 Java 对象的消息。 BytesMessage:一种主体中包含连续字节流的消息。 北京传智播客教育 www.itcast.cn

  42. 消息的传递模型 JMS 支持两种消息传递模型:点对点(point-to-point,简称 PTP)和发布/订阅(publish/subscribe,简称 pub/sub)。这两种消息传递模型非常相似,但有以下区别: PTP 消息传递模型规定了一条消息只能传递给一个接收方。 采用javax.jms.Queue 表示。 Pub/sub 消息传递模型允许一条消息传递给多个接收方。采用javax.jms.Topic表示 这两种模型都通过扩展公用基类来实现。例如:javax.jms.Queue 和javax.jms.Topic 都扩展自javax.jms.Destination 类。 北京传智播客教育 www.itcast.cn

  43. 点对点PTP 消息传递模型 北京传智播客教育 www.itcast.cn

  44. 发布/订阅消息传递模型 北京传智播客教育 www.itcast.cn

  45. 配置目标地址 开始JMS编程前,我们需要先配置消息到达的目标地址(Destination),因为只有目标地址存在了,我们才能发送消息到这个地址。由于每个应用服务器关于目标地址的配置方式都有所不同,下面以jboss为例,配置一个queue类型的目标地址。 <?xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=foshanshop"> <attribute name="JNDIName">queue/foshanshop</attribute> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> </mbean> </server> Jboss使用一个XML文件配置队列地址,文件的取名格式应遵守*-service.xml <attribute name="JNDIName">属性指定了该目标地址的全局JNDI名称。如果你不指定JNDIName属性,jboss会为你生成一个默认的全局JNDI,其名称由“queue”+“/”+目标地址名称组成。另外在任何队列或主题被部署之前,应用服务器必须先部署Destination Manager Mbean,所以我们通过<depends>节点声明这一依赖。 北京传智播客教育 www.itcast.cn

  46. 在java类中发送消息 一般发送消息有以下步骤: (1) 得到一个JNDI初始化上下文(Context) InitialContext ctx = new InitialContext(); (2) 根据上下文查找一个连接工厂 QueueConnectionFactory 。该连接工厂是由JMS提供的,不需我们自己创建,每个厂商都为它绑定了一个全局JNDI,我们通过它的全局JNDI便可获取它; QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory"); (3) 从连接工厂得到一个连接 QueueConnection conn = factory.createQueueConnection(); (4) 通过连接来建立一个会话(Session); session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); 这句代码意思是:建立不需要事务的并且能自动确认消息已接收的会话。 (5) 查找目标地址: 例子对应代码:Destination destination = (Destination ) ctx.lookup("queue/foshanshop"); (6) 根据会话以及目标地址来建立消息生产者MessageProducer (QueueSender和TopicPublisher都扩展自MessageProducer接口) 例子对应代码: MessageProducer producer = session.createProducer(destination); TextMessage msg = session.createTextMessage("您好,这是我的第一个消息驱动Bean"); producer.send(msg); 北京传智播客教育 www.itcast.cn

  47. 采用消息驱动Bean (Message Driven Bean)接收消息 消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件。它和无状态Session Bean一样也使用了实例池技术,容器可以使用一定数量的bean实例并发处理成百上千个JMS消息。正因为MDB具有处理大量并发消息的能力,所以非常适合应用在一些消息网关产品。如果一个业务执行的时间很长,而执行结果无需实时向用户反馈时,也很适合使用MDB。如订单成功后给用户发送一封电子邮件或发送一条短信等。 一个MDB通常要实现MessageListener接口,该接口定义了onMessage()方法。Bean通过它来处理收到的JMS消息。 package javax.jms; public interface MessageListener { public void onMessage(Message message); } 当容器检测到bean守候的目标地址有消息到达时,容器调用onMessage()方法,将消息作为参数传入MDB。MDB在onMessage()中决定如何处理该消息。你可以使用注释指定MDB监听哪一个目标地址(Destination)。当MDB部署时,容器将读取其中的配置信息。 北京传智播客教育 www.itcast.cn

  48. 消息驱动Bean (Message Driven Bean) @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty(propertyName="destination", propertyValue="queue/foshanshop"), @ActivationConfigProperty(propertyName="acknowledgeMode", propertyValue="Auto-acknowledge") }) public class PrintBean implements MessageListener { public void onMessage(Message msg) { 北京传智播客教育 www.itcast.cn

  49. WEB服务 Web服务也是一种分布式技术,它与EJB最大的不同是,Web服务属于行业规范,可以跨平台及语言。而EJB属于java平台的规范,尽管理论上可以跨平台,但实现起来比较复杂,所以其应用范围局限在了java平台。看上去两者好像是互相竞争的关系,其实不是。它们两者的偏重点不一样,Web服务偏重的是这个系统对外提供什么功能,而EJB偏重的是如何使用一个个组件组装这些功能。就好比一个硬盘,它对外提供的是存储服务,这是web服务的关注点,对于怎样组装这个硬盘,怎样构造这些小零件,web服务并不关心,但这些却是EJB所关注的。 JavaEE为web service提供了两种不同的编程模型:EJB容器模型及Web容器模型,这里将以最新的JAX-WS2.x规范(Java API for XML-based Web Services)介绍webservice的开发。 @WebService(targetNamespace="http://ws.foshanshop.com", name = "HelloWorld", serviceName = "HelloWorldService") 北京传智播客教育 www.itcast.cn

  50. WEB服务的客户端开发 开发步骤如下: 1. 在应用的类路径下放入JAX-WS的jar文件(下载路径:https://jax-ws.dev.java.net) 。如果你使用的是JDK6,这一步可以省略,因为JDK6已经绑定了JAX-WS。目前JDK6绑定的JAX-WS版本是2.0。这意味着,当某些应用使用的JAX-WS版本高于2.0时,就有可能发生版本问题,这时,你需要升级JDK6中的JAX-WS版本,方法如下: 下载最高版本的JAX-WS,在产品lib目录中找到jaxws-api.jar和jaxb-api.jar ,把这两个文件copy到JDK6_HOME/jre/lib/endorsed目录下。 如果有同学使用开发工具是myeclipse,这时应该把myeclipse所使用的jdk更改为你系统安装的jdk。 2. 利用Web Service客户端生成工具生成辅助类。 3. 第三步:借助辅助类调用web service。 北京传智播客教育 www.itcast.cn

More Related