服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

ejb实质问题


  为什么要使用ejb?
  ================
  
  ejb最大的诱人之处是她把应用程序和服务器分开了,我们再也不用和那些服务器上的复杂的资源打交道了,什么数据库,什么进程,线程,什么安全权限,什么套接字,都见鬼去吧,我们只需要专著于我们的商业逻辑的实现了.
  
  ==========
  ejb的实质?
  ==========
  
  ejb实际上是sun的j2ee中的一套规范,并且规定了一系列的api用来实现把ejb概念转换成ejb产品.ejb是beans,beans是什么概念,那就是得有一个容纳她,让她可劲造腾的地方,就是得有容器.ejb必须生存在ejb容器中.这个容器可是功能强大之极!她首先要包装你bean,ejb的客户程序实际上从来就不和你编写的ejb直接打交道,他们之间是通过home/remote接口来发生关系的.它负责你的bean的所有的吃喝拉萨睡,比如bean的持续化,安全性,事务管理...
  
  =============
  ejb服务器产品
  =============
  
  各个web服务器开发商基本上都在他们web服务器中新捆绑了ejb容器,或者叫ejb服务器.其中最简单也是最根本的是j2ee开发环境带的j2ee的ejb容器,它很好的和j2ee的http服务器和servlet引擎一起构筑了一个很好的运行环境,由于配置简单,功能强大,因此成为我的最爱.另外象bea的weblogical是值得推荐的一个产品,它的web服务器功能相当强大,是当今很多网站构筑的理想web服务器,它也已经加入了ejb的行列,在ejb方面有着不俗的表现.inprise的ias更是一个功能强大的web服务器,同样,也嵌入了ejb容器,加之与本公司的jbuilder的无接缝结合,更使它人气攀升.
  还有象ibm的websphere也不错,不过apache是否已经搭载了ejb容器,我不太清楚.
  另外,推荐一个ejboss,是一个完全免费的ejb服务器,而且是原代码公开的.
  
  ========================
  ejb容器如何包装你的bean.
  ========================
  
  这年头没有天上掉馅饼的好事情,ejb也不例外,你想让ejb容器替你管理你编写的ejb的吃喝拉萨睡,凭什么?!凭xml描述子,你通过一个xml文件告诉ejb容器bean的相关配置信息,比如我的ejb的home接口和remote接口是哪一个类,比如我的ejb的别名(实际上是jndi名称)叫什么,比如我的ejb是否是实体类型的ejb还是对话类型的ejb,比如告诉容器替我管理我的实体ejb中哪些自段,......总之,你得跟咱们的ejb大总管----ejb容器把所有都交代清楚.这样,剩下的,就看ejb容器的了!!!
  你是不是总共写过3个文件,bean定义,home接口定义,romote接口定义,
  当你deploy他们时,容器会
  (1).首先根据home和remote接口生成他们的实现代码,我们不妨叫做home_impl和remote_impl,
  (2).然后,利用rmic产生home_impl和remote_impl的stub和skeleton文件,2x2一共生成4个文件.
  (stub和skeleton请参见rmi的相关概念)
  如此这般,最后,在服务器上,一共有
  bean
  home_impl
  remote_impl
  home_stub
  home_skeleton
  remote_stub
  remote_skeleton
  7文件,才能让ejb工作起来.
  (3).生成实体ejb对应的数据库的库表
  (4).注册你的ejb到jndi服务
  
  ===============================================================
  为什么除了写bean,还得写接口文件,而且干嘛要home和remote两个接口.
  ===============================================================
  
  我搅着吧,这两个接口完全是可以合并成一个接口的,其实他们的作用都只是一个接口,为了让那人家sun干吗还拆成两个呢?我想,正如sun所说的,为了将一些容器相关操作和客户商业方法分开,什么意思?说开了吧,home用来规范容器相关的操作方法,remote负责专心致志的定制商业方法,而我们的bean才是最终的逻辑实现者.
  还是不明白?没关系,我在说的细些,
  举例说明:
  把我想象成一个bean,home接口就是我们家人的命令,remote接口就是我们单位的领导的命令,我们家人的命令决定了我如何吃喝拉萨睡,领导的命令决定了我如何做一些真正的工作,请注意这里我使用了"决定"这个字眼,
  我并没有说我们家人,而是说了我们家人的命令,这个命令的含义就是接口,不是类,而我这个bean却是个类!还有,bean类不实现remote和home接口,记住!记住!
  
  =========
  ejb的分类
  =========
  
  ejb分为实体(entity)ejb和对话(session)ejb,
  
  >>>>>>实体ejb:>>>>>>对话ejb<<<<<<<
  
  对话ejb根本根本不和数据库打交道,为什么,因为他根本不用序列化!他只负责来完成一些逻辑操作,比如算个帐什么的.
  为了和实体ejb较劲,他也一口气生了两个儿子,
  a.有状态(sessionful)对话ejb
  他就跟servlet中的session对象似的,可以保存用户的session相关信息,而且他仅仅被一个用户的一次session所使用,不和别人共享,我管他叫对话,不过这"对话"翻出来这是够难听的,还不如就叫他session呢!
  b.无状态(sessionless)对话ejb
  这个东东是最简单的ejb,他是可以被多个用户共享,注意!我所说的共享是指实例的共享!
  
  
  ======================================
  一个bean管理持续化的实体ejb(bmp)小例子
  ======================================
  
  说了半天了,大家珍贵的脑资源恐怕被我消耗的差不多了,好,让我们来剖析一个bean管理持续化的实体ejb(bmp)吧.
  
  -----------------------看看remote接口------------------------------
  public interface account extends ejbobject {//必须从ejbobject继承
  //这些都是商业方法,而且这里写了的,必须在bean中都实现
  public void deposit(double amt) throws remoteexception;
  public double withdraw(double amt) throws accountexception, remoteexception;
  public double getbalance() throws remoteexception;
  public string getownername() throws remoteexception;
  public void setownername(string name)throws remoteexception;
  }
  
  -------------------------看看home接口---------------------------------
  public interface accounthome extends ejbhome {
  //这声明了create函数,由于是bmp,所以必须在bean中实现一个叫ejbcreate的对应函数
  account create(string accountid, string ownername) throws createexception, remoteexception;
  
  //按主键查询
  //由于是bmp,所以必须在bean中实现一个叫ejbfindbyprimarykey的对应函数
  public account findbyprimarykey(accountpk key) throws finderexception, remoteexception;
  
  //按其中的name字段查询
  //由于是bmp,所以必须在bean中实现一个叫ejbfindbyownername的对应函数
  public account findbyownername(string name) throws finderexception, remoteexception;
  }
  
  ---------------------------看看bean-----------------------------------
  public class accountbean implements entitybean {
  //三个public字段,他们将来对应库表的三个字段
  public string accountid
  public string ownername;
  public double balance;
  
  //----home中声明的create方法的影射实现
  //由于是bmp,所以必须自己来负责实例创建时实例到数据库的影射
  public accountpk ejbcreate(string accountid, string ownername) throws createexception, remoteexception {
  preparedstatement pstmt = null;
  connection conn = null;
  try {
  this.ownername = ownername;
  this.balance = 0;
  conn = getconnection();
  pstmt = conn.preparestatement("insert into accounts (id, ownername, balance) values (?, ?, ?)");
  pstmt.setstring(1, accountid);
  pstmt.setstring(2, ownername);
  pstmt.setdouble(3, balance);
  //看这里,看这里!插进去了...
  pstmt.executeupdate();
  return new accountpk(accountid);
  }catch (exception e) {
  throw new createexception(e.tostring());
  }finally {
  try {
  pstmt.close();
  conn.close();
  }catch (exception e) { }
  }
  }
  
  //----home中声明的findbyownername方法的影射实现
  //由于是bmp,所以必须自己来完成按照name字段查找的工作
  public accountpk ejbfindbyownername(string name) throws finderexception, remoteexception {
  preparedstatement pstmt = null;
  connection conn = null;
  try {
  conn = getconnection();
  pstmt = conn.preparestatement("select id from accounts where ownername = ?");
  pstmt.setstring(1, name);
  //看看看!找上了,根据名称...
  resultset rs = pstmt.executequery();
  rs.next();
  string id = rs.getstring("id");
  pstmt.close();
  conn.close();
  return new accountpk(id);
  }catch (exception e) {
  throw new finderexception(e.tostring());
  }finally {
  try {
  pstmt.close();
  conn.close();
  }catch (exception e) { }
  }
  }

扫描关注微信公众号