实战ejb系列
在以后的日子里,cn-java由jackliu向大家陆续提供一系列ejb教程,有学习ejb的朋友请同步参考ejb相关书籍,实战系列将以例程的方式帮助你理解这些基本的概念,其中将包括:
点击查看大图
所有章节完毕后将制作成pdf电子文档,供大家下载。
实战ejb之- 开发和部署你的第一个enterprise javabean
企业javabeans(ejb)的组件结构是以作为可重复使用的服务器端组件而设计的,它使企业能够建立可升级、安全可靠、可运行于多重平台且以商务为重点的应用程序。实战ejb系列文章将以实战例程向大家全面系统介绍ejb的几种enterprise javabean概念。
在本节中你将了解到:
- 什么是企业javabeans技术?
- ejb体系结构
- ejb开发人员的角色分配
- 编写第一个ejb程序
- 部署到应用服务器
- 开发和部署测试程序
- 运行测试程序
什么是企业javabeans技术?
ejb结构是javatm平台上的服务器端组件模型。设计ejb结构的目的是, 通过使企业开发人员将注意力只集中于编写商务逻辑, 从而解决上面所提出的问题。ejb技术取消了编写"全程(plumbing)" 码的要求。例如, 企业开发人员不再需要编写那些处理事务行为、安全、连接共享或线程的代码, 因为ejb体系结构将这些任务委托给服务器厂商完成了。
对用户和这一技术的实现者来说, 将会获得如下收益:
? 生产效率: 使用这一技术, 企业开发人员将会进一步提高生产效率。他们不仅能够获得在java平台上的开发成果, 而且能够将注意力集中于商务逻辑, 从而使效率倍增。
? 业内支持: 试图建立ejb系统的客户会获得一系列可供选择的解决方案。企业javabeans技术已经被多达25个公司所接受、支持和应用。
? 投资保护: 企业javabeans技术建立在企业现存系统之上。事实上, 许多ejb产品都将建立在已有的企业系统之上。今天企业所使用的系统, 明天将会运行企业javabeans组件。 ? 结构独立: 企业javabeans技术将开发人员和底层中间件相隔离; 开发人员看到的仅仅是java平台。 这一点除下面将要谈到的交叉平台的好处外, 还将使得ejb服务器厂商在不干扰用户的ejb应用程序的前提下, 有机会改进中间件层。
? 服务器端仅写一次, 即可随处运行(server-side write once, run anywheretm): 通过对java平台的支持, ejb技术将"仅写一次, 随处运行"的概念提高到了一个新的水平。它可以保证一个ejb应用程序可运行于任何服务器, 只要这个服务器能够真正提供企业javabeans apis。
ejb体系结构
理解ejb体系结构可以从两个方面分析:客户端和服务器端。 ejb体系结构的客户端包含了调用ejb组件特定业务所需的ejb接口(扩展了ejbhome和ejbobject接口的组件接口),同时还包含了服务器端处理对象的句柄(部署组件时生成的残根类)。在ejb体系结构的服务器端则包含了ejb组件实现的实例,同时还包含了用来在客户端与ejb组件之间进行映射的容器代码。结构如下图1-1:
<图1>
ejb客户应用程序使用jndi来查找对本地接口的实例引用,通过本地ejb接口和远程ejb主接口调用和引用ejb组件的全部方法和属性。
开发人员的角色分配
ejb技术将开发人员分成固有的五种角色: 服务器提供者、 容器提供者、 企业beans提供者、 应用程序装配者和部署者。对上述五种角色描述如下:
? 服务器提供者是分布式事务管理方面的专家, 主要负责处理分布式对象和低层次系统服务。数据库和tp监控器厂商可典型地充当该角色。
? 容器提供者一般是系统编程方面的专家, 由于容器有能力将ejb环境与现存应用程序(如sap r/3和cics)桥接起来, 因而这些专家有可能具备某一应用领域的经验。由于容器为bean提供了安全、可升级和事务性的环境, 因而容器提供者需具备这些领域的经验。数据库和事务服务器厂商也适合这一角色, 并可提供标准容器。
? 企业beans提供者为ejb应用程序提供"积木", 他们是典型的以bean的形式编写商务逻辑的域专家,而他们不一定是数据库或系统编程方面的专家。他们生成包括所有组件在内的ejb jar文件。对象库厂商适合这一角色。
? 应用程序装配者是域专家, 他们的工作是用第三方beans建立应用程序, 他们也有可能建立客户端gui。典型的应用程序装配者通常是程序员,他们建立应用程序来可访问已部署的组件。
? 部署者通常熟悉企业的操作环境, 他们利用应用程序包并设置部分或全部应用程序的安全和事务描述符。部署者也有可能使用工具来修正bean的商务逻辑。
编写第一个ejb程序
开发一个ejb至少包括四个步骤:
- 开发主接口
- 开发组件接口
- 开发bean实现类
- 编写部署文件
我们将编写一个最简单session bean来实现这四个元素,这个例子将通过一个gethello()方法返回一个"hello, ejb"字符串,并为这个bean起一个好听的名字:hello
注意:假设你使用的windows操作系统,这与程序代码和部署文件内容无关,但这些仅可能影响到存储路径和命令行。
1.开发主接口:
是由bean开发人员编写的一个bean的主接口(interface)程序,负责控制一个bean的生命周期(生成、删除、查找bean)。只需要开发人员给出一个主接口类,类方法的实现由容器来完成。所以开发一个bean的接口程序是非常的简单的。 一般情况下,习惯将主接口的命名规则规定为home,所以我们把这个主接口类起名为hellohome
hellohome.java代码:
public interface hellohome extends javax.ejb.ejbhome{ public hello create() throws java.rmi.remoteexception, javax.ejb.createexception; }
|
假设我们保存到d:ejbhellosrchellohome
java 接口类hellohome扩展了javax.ejb.ejbhome类,这个类不在标准的sdk开发包中,需要你的开发机安装有j2ee的sdk。所有深入的解说我们将略去,留在以后章节的例子中讲述。
2.开发组件接口:
当远程用户调用主接口类生成方法(create())时,客户要得到一个组件的远程引用,因此ejb容器要求你为这个bean的所有方法提供一个接口类,类的实现则与主接口一样由容器在部署时自动生成。 一般情况下,习惯将组件接口的命名规则规定为,所以我们把这个组件接口类起名为hello
hello.java代码:
public interface hello extends javax.ejb.ejbobject{ public string gethello() throws java.rmi.remoteexception; }
|
假设我们保存到d:ejbhellosrchello.java
3.开发bean实现类:
包含了业务类的所有详细设计细节,在这里我们将通过gethelloejb()方法返回一个"hello, ejb"字符串。 一般情况下,习惯将bean的实现类命名规则规定为ejb,所以我们把这个类起名为helloejb
helloejb.java代码:
import javax.ejb.*; public class helloejb implements sessionbean{ public void ejbcreate(){} public void ejbremove(){} public void ejbactivate(){} public void ejbpassivate(){} public void setsessioncontext(sessioncontext ctx){}
public string gethello() { return new string("hello,ejb"); } }
|
假设我们保存到d:ejbhellosrchelloejb.java
到此为止我们的bean程序hello已经编写完毕了,使用如下命令进行编译:
cd ejbhello mkdir classes cd src javac -classpath %classpath%;../classes -d ../classes *.java
|
如果顺利你将可以在..helloclasses目录下发现有三个类文件,恭喜你,你已经迈出了第一步!不过后面还要有很多的事情要做,因为我们的bean还没有部署到容器里,现在只是普普通通的三个java类。因为bean是没有界面的,所以我们还要为它编写一个测试这个bean的测试程序。刚松了口气就又要下面的旅程了,不过,我们期待着的hello,ejb在向我们靠近。
4.编写部署文件:
一个完整的ejb是由java类和一个描述其特性的ejb-jar.xml文件组成,,部署工具将根据这些文件部署到容器中,并自动生成容器所需的类。 按照下面个格式编写一个ejb-jar.xml文件
ejb-jar.xml文件:
<?xml version="1.0" encoding="utf-8"?> <!doctype ejb-jar public "-//sun microsystems, inc.//dtd enterprise javabeans 2.0//en" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <description> this is hello ejb example </description> <display-name>hellobean</display-name> <enterprise-beans> <session> <display-name>hello</display-name> <ejb-name>hello</ejb-name> <home>hellohome</home> <remote>hello</remote> <ejb-class>helloejb</ejb-class> <session-type>stateless</session-type> <transaction-type>container</transaction-type> </session> </enterprise-beans> </ejb-jar>
|
假设我们将文件保存到d:ejbhelloclassesmeta-infejb-jar.xml(注意meta-inf必须大写)
部署到应用服务器
在部署之前我们需要将这些类文件和xml文件做成一个jar文件,ejb jar文件代表一个可被部署的jar库,在这个库里,包含了服务器代码与ejb模块的配置。ejb-jar.xml文件被放置在jar文件所指定的meta-inf目录中。我们可以使用如下命令得到ejb jar文件:
cd d:ejbhelloclasses (要保证类文件在这个目录下,且有一个meta-inf子目录存放ejb-jar.xml文件) jar -cvf hello.jar *.*
|
部署工具一般由java应用服务器的制造商提供,在这里我使用了apusic应用服务器,并讲解如何在apusic应用服务器部署这个hello组件。
注意,如果使用其他部署工具,原理是一样的,要使用apusic应用服务器,可以到www.apusic.com上下载试用版。
确定你的apusic服务器已经被启动。打开"部署工具"应用程序,点击文件->新键工程:
第一步:选择"新建包含一个 ejb组件打包后的ejb-jar模块"选项
第二步:选择一个刚才我们生成的hello.jar文件
第三步:输入一个工程名,可以随意,这里我们输入hello
第四步:输入工程存放的地址,这里我们假设被存放到d:ejbhellodeploy目录下
完成四个步骤后,如果没有问题将出现hellbean的部署界面,因为这个例子非常的简单,所以不需要任何的配置,点击部署->部署到apusic应用服务器完成部署工作。
图 1-2
如果看到上述画面,恭喜你,你的bean已经被部署到ejb容器中,其他部署工具不再详述。
开发和部署测试程序
一个ejb组件是没有任何运行界面的,所有组件的实例都被容器所管理,所以我们要测试这个bean组件,需要写一段测试程序,简单期间,我们写一段小服务程序(java servlet)。
关于如何编写servlet我们这里不做介绍,下面是提供的代码:
helloservelt.java文件:
import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import javax.ejb.*; import javax.naming.initialcontext;
public class helloservlet extends httpservlet{
public void service(httpservletrequest req,httpservletresponse res) throws ioexception { res.setcontenttype("text/html"); printwriter out =res.getwriter(); out.println("<head></head>"); try{ initialcontext ctx=new initialcontext(); object objref = ctx.lookup("java:comp/env/ejb/hello"); //主接口 hellohome home=(hellohome)javax.rmi.portableremoteobject.narrow( objref,hellohome.class); //组件接口 hello bean =home.create(); out.println(bean.gethello()); }catch(javax.naming.namingexception ne){ out.println("naming exception caught:"+ne); ne.printstacktrace(out); }catch(javax.ejb.createexception ce){ out.println("create exception caught:"+ce); ce.printstacktrace(out); }catch(java.rmi.remoteexception re){ out.println("remote exception caught:"+re); re.printstacktrace(out); } out.println(""); } }
|
假设我们将文件保存到d:ejbhellosrchelloservlet.java
回到src目录下,使用如下命令编译servlet
javac -classpath %classpath%;../classes -d ../classes helloservlet.java
|
成功编译后,将这个servlet一同部署到hello工程中,我们回到"部署工具",点击编辑à填加一个web模块。
图1-3
部署注意事项:
在hello属性页的"www根路径"是访问这个servlet的相对路径,切记。
在hello内容属性一页中,展开web-inf,选择classes,单击"添加类"按钮按照下图添加这个servlet类
图1-4
在hello配置属性一页中,单击"11.模块中用到的ejb的定义"按照图1-5进行设置
图1-5
点击部署->部署到apusic应用服务器完成部署工作。
运行测试程序
打开浏览器,在浏览器中输入:
http://localhost:6888/hello/servlet/helloservlet
localhost-代表web server的主机地址
6888-应用服务器端口,根据不同的应用服务器,端口号可能不同
hello-我们部署servlet时指定的www根路径值 servlet-ejb容器执行servlet的路径
helloservlet-测试程序
|
|