⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 19.html

📁 写给JSP初级程序员的书
💻 HTML
📖 第 1 页 / 共 4 页
字号:
      ejbPassivate() throws RemoteException;<BR>public void ejbRemove() throws 
      RemoteException;<BR>public void setSessionContext(SessionContext 
      context)<BR>throws 
      RemoteException;<BR>}<BR>javax.ejb.EnterpriseBean是一个空接口,是会话bean和实体bean的超类。<BR><BR><B>会话bean的交换</B><BR><BR>  容器开发商可以实现把会话bean的实例从主存移到二级存储中的交换机制,这可以增加一段时间内实例化的会话bean的总数。容器维护一个bean的时间期限,当某个bean的不活动状态时间达到这个阙值,容器就把这个bean拷贝到二级存储中并从主存中删除。容器可以使用任何机制来实现bean的持久性存储。最常用的方式是通过bean的串行化。Bean开发者在bean中应避免使用transient 
      fields。EjbActivate()和ejbPassivate()用来维护这个fields值。<BR><BR><B>活化和钝化<BR></B><BR>  为了支持厂商提供会话bean的交换,规范定义了钝化--把bean从主存转移到二级存储的过程,活化--把bean恢复到主存中去的过程。在SessionBean接口中声明的EjbActivate()和ejbPassivate()方法,允许容器通知已经被活化的bean它将要被钝化。Bean开发者可以用这些方法释放和恢复处于钝化状态的bean所占有的值、引用和系统资源。一个可能的例子是数据库连接,作为有限的系统资源,不能被钝化的bean使<BR>用。<BR><BR>  有了这些方法就使得不必在使用transient.事实上,使用transient可能是不安全的,因为串行化机制自动地把值设为null或0。而通过ejbActivate()和ejbPassivate()方法显式地设置这些fields更好一些。依靠Java的串性化机制把transient 
      fields设成null也是不可移植的,因为当bean部署在不使用Java的串性化机制获得持久性的EJB容器中时该行为会发生改变。如果容器不提供交换,那么这些方法将永远不会被调用。 
      当客户端调用bean的商业方法时钝化的bean被激活。当EJBObject收到方法调用的请求时,它通知容器需要活化的bean.当活化完成时,EJBObject代理对bean的方法调用。 
      如果bean 
      参与一个事务,那么它不能被钝化。把bean放在主存中更有效率,因为事务通常在很短的时间内完成。如果bean没有钝化前必须释放或活化前必须重置的状态,那么这些方法可置空。在大多数情况下,bean开发者不必在这些方法中做任何事。<BR><BR><B>会话bean的状态管理<BR></B><BR>  会话bean的部署描述符必须声明该bean是有状态或无状态的。一个无状态bean是在方法调用间不维护任何状态信息的bean。通常,会话bean的优点是代替客户端维护状态。然而,让会话bean无状态也有一个好处。无状态bean不能被钝化。因为它不维护状态,所以没有需要保存的信息。容器可以删除bean的实例。客户端永远不会知道无状态bean的删除过程。客户端的引用是EJBObject.如果客户端稍后又调用了一个商业方法,则EJBObject通知容器在实例化一个新的会话bean.因为没有状态,因此也没有信息需要恢复。<BR><BR>  无状态bean可以在客户端间共享,只是在某一时刻只能有一个客户端执行一个方法。因为在方法调用间没有需要维护的状态,所以客户端可使用任何无状态bean的实例。这使 
      得容器可以维护一个较小的可服用bean的缓冲池,节省主存。因为无状态bean在方法调 用间不能维护状态,因此从技术上讲在home 
      interface的create()方法不应有参数。在任何无状态bean的实例。这使 
      得容器可以维护一个较小的可服用bean的缓冲池,节省主存。因为无状态bean在方法调 用间不能维护状态,因此从技术上讲在home 
      interface的create()方法不应有参数。在创建时向bean传递参数意味着在ejbCreate()返回时需要维护bean的状态。而且,经由EJBObject调用商业方法的结果使得容器必须能重创建一个无状态的bean.这时在开始创建bean时的参数就不存在了。厂商的安装工具应该能检查home 
      interface的无状态对话bean以保证其不包含带参数的create()方法。<BR><BR><B><FONT 
      color=#ff0033>实体bean</FONT></B><FONT 
      color=#ff0033><BR></FONT><BR><B>实体bean的角色</B><BR><BR>  实体bean用来代表底层的对象。最常用的是用实体bean代表关系库中的数据。一个简单的实体bean可以定义成代表数据库表的一个记录,也就是每一个实例代表一个特殊的记录。更复杂的实体bean可以代表数据库表间关联视图。在实体bean中还可以考虑包含厂商的增强功能,如对象--关系映射的集成。<BR><BR>  通常用实体类代表一个数据库表比代表多个相关联的表更简单且更有效。反过来可以轻易地向实体类的定义中增加关联,这样可以最大地复用cache并减小旧数据的表现。<BR><BR><B>实体bean和对话bean的比较</B><BR><BR>  看起来会话bean好象没什么用处,尤其对于数据驱动的应用程序。当然事实并不是这样。因为实体bean(譬如说)代表底层数据库的一行,则实体bean实例和数据库记录间就是一对一的关系。因为多个客户端必须访问底层记录,这意味着,不同于会话bean,客户端必须共享实体bean。因为是共享的,所以实体bean不允许保存每个客户端的信息。会话bean允许保存客户端的状态信息,客户端和会话bean实例间是一对一的。实体bean允许保存记录的信息,实体bean实例和记录间是一对一的。一个理想的情况是客户端通过会话bean连接服务器,然后会话bean通过实体bean访问数据库。这使得既可以保存客户端的信息又可以保存数据库记录的信息。<BR><BR><IMG 
      height=244 src="ejb_img2.jpg" tppabs="http://www.chinajavaworld.com/doc/ejb/images/ejb_img2.jpg" 
      width=492><BR><BR>  同时会话bean也不能提供在相同或不同的EJB类调用间进行全局的事务控制。没有会话bean,应用程序开发者(客户端开发者)就必须理解EJB类的事务要求,并使用客户端的事务划分来提供事务控制。EJB的主要好处就是应用开发者不需知道EJB类的事务需求。一个会话bean可以代表一个商业操作,进行事务控制,不需要客户端进行事务划分。<BR><BR><B>Finder方法<BR></B><BR>  通过home或remote 
      interface创建和删除bean的实例,对实体bean和会话bean来说有不同的含义。对会话bean来说,删除意味着从容器中删除,不能再使用,并且其状态信息也丢失了。对于实体bean,删除意味着底层数据库记录被删除了。因此,一般不把删除作为实体bean生命周期的一部分。<BR><BR>  创建一个实体bean意味着一个记录被插进数据库中。与删除操作类似,创建操作通常也不作为实体bean生命周期的一部分。客户端访问实体bean需要先找到它。除了create()方法,一个实体bean的home 
      interface还有finder方法。客户端需要根据应用程序的限制来识别一个特殊的数据库记录。例如:<BR><BR><BR><BR>public 
      interface AccountHome extends EJBHome {<BR>public Account 
      findByFirstLast(String first, String last)<BR>throws 
      RemoteException,FinderException;<BR>public Account 
      findByAccountNumber(String acctNum)<BR>throws 
      RemoteException,FinderException;<BR>}<BR><BR>  当客户端调用home 
      object的任何方法,容器把调用传递到实体bean的相应方法中。<BR><BR>Public class myEntityBean 
      implements EntityBean {<BR>…<BR>public Obejct ejbFindByFirstLast(String 
      first, String last) {<BR>//runs appropriate singleton SELECT 
      statement<BR>//returns primary key for selected row<BR>}<BR>public Obejct 
      ejbFindByAccountNumber(String acctNum) {<BR>//runs appropriate singleton 
      SELECT statement<BR>//returns primary key for selected 
      row<BR>}<BR>}<BR><BR><BR>  一个较好的方法是把finder方法当成数据库的SELECT语句,而动态SQL参数相当于方法的参数。注意home 
      interface中的finder方法向客户端返回一个对EJBObject的远程引用。Bean中的Finder方法向容器返回一个唯一的标识符,称为主键。容器用这个主键实例化一个代表选定的记录的EJBObject。不论如何实现finder方法,容器都用这个主键代表这个选定的记录,由实体类来决定如何用唯一的标识符来代表记录。<BR><BR>  由可能一个finder方法得到满足SELECT语句条件的多个记录。这种情况下bean的finder方法返回一个主键的枚举类型。Home 
      interface的Finder方法定义成向客户端返回EJBObject引用的枚举类型。<BR><BR>Public interface 
      AccountHome extends EJBHome {<BR>…<BR>public Enumeration 
      findByCompany(String companyName)<BR>throws 
      RemoteException,FinderException;<BR>}<BR>public class myEntityBean 
      implements EntityBean {<BR>…<BR>public Enumeration ejbFindByCompany(String 
      companyName) {<BR>//runs appropriate SELECT statement<BR>//returns an 
      Enumeration of primary 
      keys<BR>}<BR>}<BR><BR><B>主键</B><BR><BR>  主键这个词有可能被曲解。把它理解为唯一的标识符更恰当些。当实体bean代表一个数据库记录时,主键可能是该记录的组合键。对于每个实体bean的实例,有一个相应的EJBObject.当一个EJBObject与一个实体bean实例对应时,该实例的主键保存在EJBObject中。<BR><BR>  这时说该实体bean的实例有一个标识符。当客户端调用home 
      object的finder方法时,容器会用没有标识符的实体bean的实例来执行这个请求。容器可能为此维持一个甚至多个匿名的实例。不论如何实现finder方法,都必须向容器返回底层数据的主键,如数据库的记录。如果多个记录满足条件,那么就返回多个主键。当容器得到主键后,它会用该主键初始化一个EJBObject.容器也可以初始化一个与每个EJBObject关联的实体bean的实例。因为底层记录的标识符在EJBObject中保存,因此在bean实例中没有状态。因此,容器可以在EJBObject上调用商业方法时再实例化bean,以节省内存资源。<BR><BR>  当finder方法向容器返回主键时,容器首先会检查该主键的EJBObject是否已经存在。如果该主键的EJBObject已经存在,那么容器不会创建一个新的EJBObject,而是向客户端返回这个已存在的EJBObject的引用。这样就保证了每个记录只有一个EJBObject的实例,所有的客户端共享EJBObject.<BR><BR>  主键只是在该类中唯一地标识bean的实例,容器负责保证其范围。应该明确finder方法只是从数据库中取出数据的主键,而不包含其它的数据项。也可能调用finder方法后不产生任何实体bean的实例,只产生包含该主键的EJBObject,当客户端调用EJBObject的方法时在产生并导入实体bean的实例。 
      Home object保证客户端可以访问以下方法:<BR>public myRem findByPrimaryKey(Obejct key) 
      throws …;<BR>EJBObject提供以下方法的一个实现:<BR>Public Object 
      getPrimaryKey();<BR><BR>  客户端能在任何时候获得实体bean的主键,并且以后可以使用该主键通过home 
      interface重建对实体的引用。主键类的类型在部署描述符中指定。Bean开发者可以用任何类类型来表示主键。唯一的要求是类必须实现serializable,因为主键可能在客户和服务器间传递。<BR><BR>*********</SPAN></P>
      <P><SPAN 
      class=txt><B>实体bean的内外存交换</B><BR><BR>  现在应该来看看javax.ejb.EntityBean接口。<BR>public 
      interface javax.ejb.EntityBean extends EnterpriseBean {<BR>public void 
      ejbActivate() throws RemoteException;<BR>public void ejbPassivate() throws 
      RemoteException;<BR>public void ejbRemove() throws 
      RemoteException,RemoveException;<BR>public void 
      setEntityContext(EntityContext ctx) throws RemoteException;<BR>public void 
      unsetEntityContext() throws RemoteException;<BR>public void ejbLoad() 
      throws RemoteException;<BR>public void ejbStore() throws 
      RemoteException;<BR>}<BR><BR>  活化和钝化的过程与会话bean类似。然而,不在事务中的实体bean是无状态的;其状态总是和底层的数据同步的。如果我们象钝化会话bean那样钝化实体bean,则当钝化无状态实体bean时只会删除它。但是因为容器调用finder方法需要匿名的实体bean,容器可 
      能为此把不活动的实体bean钝化到一个私有内存池中。一旦从EJBObject中删除实体 bean,则同时删除了标识符(主键关联)。 
      当客户端调用没有相关的实体bean的EJBObject的商业方法时,容器就可能用这个内存池重新分配实体bean. 
      注意这个内存池中的bean没有标识,可以被任何EJBObject重用。容器可以可以不维护任何有EJBObject的实体bean,除非有一个商业方法在通过EJBObject被调用。如果实体bean在事务中则需保持其与EJBObject的关联。<BR><BR><B>自管理的持久性<BR></B><BR>  因为实体bean代表底层的数据,因此我们需要把数据从数据从数据库中取出然后放在bean中。当容器第一次把一个实体bean的实例与EJBObject关联时,它就开始了一个事务并调用了这个bean的ejbLoad()方法。在这个方法中开发者必须提供从数据库中取出正确的数据并把它放在bean中。当容器将要提交一个事务它首先调用bean的ejbStrore()方法。这个方法负责向数据库中回写数据。我们称之为自管理持久性,因为bean方法中的代码提供了这种同步。当ejbLoad()方法完成时,bean有可能与底层数据库不一致。商业方法的调用触发了与EJBObject关联的bean的分配,然后在事务中执行的ejbLoad()必须在部署描述符中声明。根据接收到的方法调用请求,EJBObject和容器一起建立一个事务上下文。容器分配EJBObject的bean并调用bean的ejbLoad()方法。这个方法现在运行在事务上下文中。这个事务上下文传递给数据库,根据部署描述符中指定的孤立性级别,这个事务锁定数据库中被访问的数据。只要事务上下文活动,数据库中的数据就一直保持锁定状态。当客户端或容器提交事务时,容器首先调用bean的ejbStore()方法,把bean中的数据回写到数据库中。相应的数据库记录在ejbLoad()和ejbStore()间保持锁定保证了bean和数据库间的同步。其间可以进行不同的商业方法调用。而且,ejbLoad()和ejbStore()明确地区分了事务边界,事务中可以进行任何商业方法调用。事务的持续时间由部署描述符决定,也可能由客户端决定。注意不必使用ejbActivate()和ejbPassivate()方法来执行与数据库间的同步。<BR><BR><B>容器管理的持久性<BR><BR>  </B>如果部署描述符声明bean使用容器管理的持久性,则不用ejbLoad()和ejbStore()来访问数据库。容器会把数据从数据库中导入到bean中,然后调用bean的ejbLoad()方法来完成从数据库中接收数据。同样地,容器调用bean的ejbStore()方法来完成把数据回写到数据库中。这些方法实际 
      上没有执行任何数据库操作。当开发商用复杂的工具来提供容器管理持久性时,如自动产生能进行对象--关系映射的实体bean类,规范规定了厂商必须提供的容器管理实体持久性的最小需求集。部署描述符可以指定bean的一个public域来实现与数据库列简单映射。容器使用部署描述符读出bean的这个public域并写到相应的列,或从数据库列中读出数据写到public域中。容器管理的持久性对EJB开发者来说是非常好的服务,且不需对象--关系影射等其他复杂的机制,开发者会发现它比自管理的持久性更有效率。<BR><BR><B>部署描述符</B><BR><BR><B>区分EJB开发的角色</B><BR><BR>  EJB开发中两个主要的角色是bean开发者和bean部署者。有很多属性开发者不能预知,如数据库的网络地址,使用的数据库驱动程序等等。部署描述符作为由开发定义的特性表,由部署者添入正确的值。部署描述符有标准的格式,在开发和部署环境中是可移植的,甚至在不同EJB平台间也是可移植的。 
      Enterprise 
      bean的行为控制除了为开发和部署的协同提供一个标准的属性单,部署描述符也应包含bean应如何执行有关事务和安全的细节信息。一些如访问控制链(ACL)等属性,也应该由部署者来调整以保证适当的用户能在运行时使用bean.其它属性,如事务信息,有可能完全由开发者指定,因为一般由开发者创建数据库访问代码,并熟知bean的方法应如何运行事务。<BR><BR><B>定义部署描述符<BR></B><BR>  部署描述符是一个标准的Java类。创建一个实例,导入数据,然后串行化。这个串行化的部署描述符放在一个jar文件中并和enterprise 
      bean类一起送到部署环境。部署者读取这个串行化的部署描述符,可能修改一些属性值,然后使用这个修改后的部署描述符来安装enterprise 
      bean.<BR><BR>  下面是部署描述符的一部分内容。它是两个其它的部署描述符类的超类。实际上超类是描述这个bean的描述符。<BR><BR>Javax.ejb.deployment.DeploymentDescriptor<BR>?bean 
      home name<BR>?bean class name<BR>?home interface class name<BR>?remote 
      interface class name<BR>?environment properties<BR>?control 
      descriptors<BR>?access control 
      list<BR><BR>DeploymentDescriptor有两个子类:<BR><BR>javax.ejb.deployment.SessionDescriptor<BR>?state 
      management type<BR>?session 
      timeout<BR><BR>javax.ejb.deployment.EntityDescriptor<BR>?list of 
      ocntainer-managed fields<BR>?primary key class 
      name<BR><BR>  描述符为实体bean和每个方法定义了事务和安全属性。这些对象的一个数组在<BR>DeploymentDescriptor中指定。<BR><BR>javax.ejb.deployment.ControlDescriptor<BR>?transaction 
      isolation level<BR>?Method object to which this descriptor 
      applies<BR>?run-as mode(for odentity mapping)<BR>?run-as identity(for 
      identity mapping)<BR>?transaction attribute<BR><BR><BR>  部署一个enterprise 
      bean时,分配对应的描述符,然后初始化,串行化,再将其与enterprise 
      bean类一起放入到一个jar文件中。不同厂商在定义部署描述符时可能有不同的方式。例如,一个厂商可能使用文本方式,而另一厂商可能提供图形工具。但最后结果的部署描述符是一个标准的格式,并且在不同平台间是可移植的。<BR><BR><B>EJB 
      Jar文件</B><BR><BR>  为了包装一个enterprise 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -