《高级软件工程》PPT课件.ppt

上传人:za****8 文档编号:12727459 上传时间:2020-05-20 格式:PPT 页数:76 大小:385.56KB
返回 下载 相关 举报
《高级软件工程》PPT课件.ppt_第1页
第1页 / 共76页
《高级软件工程》PPT课件.ppt_第2页
第2页 / 共76页
《高级软件工程》PPT课件.ppt_第3页
第3页 / 共76页
点击查看更多>>
资源描述
第十讲构件运行环境,构件运行环境对于软件构件的重要性完全类似于操作系统对作业的重要性构件运行环境的出现甚至正在改变网络软件的高层运行模式,内容,概述构件容器的功能容器与实现体的合作会话构件实例的管理实体构件实例的管理,一、概述,从运行环境角度看面向对象技术与构件技术1、构件上下文2、构件容器3、构件约束,1构件运行环境主要关心哪些问题?,1、构件上下文我们日常生活中的任何语言都有一定的上下文(语境)同样一句话由不同的人说出来其含义可能不同由同一个人说出来但由不同的人听起来其含义也可能不同完全相同的听说两个人在不同的环境中说的相同一句话含义也可能不同不同的地点、不同的时间、不同的旁听者等共同构成了语言的语境,在网络环境中一个计算过程(构件)受环境的影响很大例如:客户的身份服务体能提供的访问带宽客户的请求方式等都会对构件的具体服务方式产生影响例如:是否为客户提供服务提供何种精度的服务使用什么样的交互协议等上述影响构件服务效果的各种因素都被认为是构件的上下文构件运行环境需要为构件获取这些信息并帮助构件做出适当的反应,2、构件容器在编程语言中每个数据对象都是数据值的容器COM套间通过线程模型将不同的对象分割到不同的运行空间中使得它们的运行相对独立MTS引入了事务性上下文概念共享相同事务域的多个对象处于同一个线程中这同样将它们与系统的其他部分隔离开来在.NET的CLR中同时吸取了COM与MTS中的上述技术跨越上下文的访问被执行引擎所控制并可能进行一些特殊处理EJB模型中的容器概念比较完善除了采用类加载器分别加载不同的构件外EJB容器还为EJB构件实例承担了记录上下文、控制生命周期、控制对实例的访问等任务,3、构件约束构件约束是关于构件所实现功能的约束这些约束传统上被编写到构件代码中但由于这样往往导致系统约束性需求的实现分布在不同的构件代码中不利于约束需求的演化可以利用一些新技术将构件约束的实现与构件的功能代码进行分离以便于对这些约束进行统一实施截取器即是针对上述问题的一种解决实现机制,截取器是一种十分重要的设计模式用于在构件接收消息与发送消息过程中对消息进行截取以进行必要的加工或处理例如:在构件为客户的请求进行服务之前检查安全上下文,以决定是否为构件服务检查事务上下文,以决定为构件提供什么样的可靠性支持对客户的请求进行记录,以供将来分析系统的运行状况在构件为客户的请求进行服务之后检查结果返回值,确认返回值的有效性等通过引入构件截取器可以将构件代码中与业务逻辑无关的约束性内容剥离出来由截取器与一些公共服务互相配合共同完成构件约束性需求的实现这不仅使构件代码更为简洁还提高了应用系统的适应性,二、构件容器的功能,网络环境中的软件必须考虑客户访问量问题一个拥有大量用户的系统可能需要同时运行成千上万的对象如果不控制系统资源的使用将使系统因为资源不足而大大降低响应时间甚至导致系统不可用应用服务器通过容器对大量构件实例的有效管理来提高系统的资源利用率所依赖的主要机制为:实例池冻化/活化生命周期管理等,1、实例池,实例池技术是系统软件中普遍使用的共享技术其核心思想是将暂时不用的资源实例缓存起来放到实例池中当下一个客户需要访问资源时直接从实例池中取出来为客户服务实例池技术带来的好处主要有两方面:其一,有效地减少对实例频繁的创建与删除工作提高了响应速度其二,通过设定实例池的大小可以限制访问客户的数目以保证正在访问客户的服务质量实现构件实例池的基本方法是:在加载系统时,为一个构件类型创建多个实例。当一个客户提出请求时,从实例池中提取构件实例建立起与客户的关联当客户不再需要构件服务时,将实例放回实例池,2、冻化/活化,有态构件不同于无态构件的地方在于:有态构件保持一个业务过程中前后方法调用之间的状态这个状态代表着有态构件实例与其客户之间的一个对话对有态构件实例进行有效资源管理的技术是冻化、活化技术当一个构件实例的访问频率较低而此时又有大量客户需要服务时可以将这个有态构件实例挂起以减少系统中构件实例的数目挂起有态构件的实例需要保持其话态,实例的状态将被序列化序列化构件实例时除了需要将该实例从内存中暂时删除外还需要将该实例的状态保存到外存中(例如一个文件系统等)当这个实例的客户再次访问该实例时容器将首先构造一个新实例然后从外存中取出实例的状态并恢复实例的状态冻化/活化技术也适用于实体构件,3、生命周期管理,构件的实现体一般随着应用系统的部署被加载到应用服务器中被构件容器所管理例如:创建构件实例查找构件实例删除构件实例接收客户请求消息等构件的生命周期管理主要是指构件实例的生命周期管理,三、容器与实现体的合作,为了完成客户的请求构件容器与构件实现体必须进行很好地分工与协作:如果请求与类型接口中的方法相对应则主要由构件容器负责进行构件的创建、查找、删除等操作尽管最终可能还是需要构件实现体的介入如果请求与实例接口中的方法相对应则说明这是与构件业务逻辑相关的请求必须由构件实现体进行服务容器将代理客户向构件实现体发送这些业务请求1、构件实现体向容器提供的方法2、容器向构件实现体提供的方法3、构件实现体与构件接口的方法,1、构件实现体向容器提供的方法容器是构件的“操作系统”构件实现体所有的方法都是通过容器发生作用的这些方法可以被大体分为两类一类是通过容器提供给客户的另一类是专门提供给容器以供管理的后者包括:基本接口EnterpriseBean用于定义会话构件的接口SessionBean用于定义实体构件的接口EntityBean以及对于会话构件可选的接口SessionSynchronization,2EJB构件与构件运行环境之间的接口有哪些?,EnterpriseBean只表明任何构件都是可序列化的:packagejavax.ejb;importjava.io.Serializable;publicinterfaceEnterpriseBeanextendsSerializable,所有会话构件必须实现SessionBean接口:packagejavax.ejb;importjava.rmi.RemoteException;publicinterfaceSessionBeanextendsEnterpriseBeanpublicabstractvoidejbActivate()throwsEJBException,RemoteException;publicabstractvoidejbPassivate()throwsEJBException,RemoteException;publicabstractvoidejbRemove()throwsEJBException,RemoteException;publicabstractvoidsetSessionContext(SessionContextsessioncontext)throwsEJBException,RemoteException;,setSessionContext将当前会话构件实例与由容器管理的Context(事务Context、安全Context等)进行关联并将其作为话态的一部分ejbRemove用于由容器将构件实例删除ejbRemove方法与ejbPassivate释放的资源基本一样ejbPassivate用于由容器冻化实例ejbActivate用于由容器活化实例由于容器自动利用Java语言的序列化机制进行冻化、活化过程上述操作在构件开发过程中大多数可忽略,对于会话构件:可选的SessionSynchronization接口packagejavax.ejb;importjava.rmi.RemoteException;publicinterfaceSessionSynchronizationpublicabstractvoidafterBegin()throws.;publicabstractvoidafterCompletion(booleanflag)throws.;publicabstractvoidbeforeCompletion()throws.;,会话构件可以有选择性地实现SessionSynchronization接口这个接口提供了一些同步通告实例可以用这些方法在事务中管理数据的缓冲等afterBegin方法用于标明新事务的开始container在事务内的第一个business方法前调用它beforeCompletion方法用于标明客户已经完成当前事务的工作但是还没有提交给实例使用的资源管理者此时实例应该写出缓冲的数据实例可在sessioncontext中调用setRollbackOnly来卷回原来状态afterCompletion方法用于标明当前transaction已经结束结束状态true表示已提交false表示已卷回因为会话构件实例的话态不是事务性的卷回后需要手动调整它的状态,关于SessionSynchronization:所有容器提供者必须支持SessionSynchronization它仅只对构件实现者可选.只有容器管理事务的有态会话构件可以实现SessionSynchronization;无态会话构件不允许实现SessionSynchronization。构件管理事务的会话构件不必依赖SessionSynchronization因为构件自身管理事务不必向容器提供同步机制,packagejavax.ejb;importjava.rmi.RemoteException;publicinterfaceEntityBeanextendsEnterpriseBeanpublicabstractvoidsetEntityContext(EntityContextentitycontext)throws;publicabstractvoidunsetEntityContext()throws;publicabstractvoidejbActivate()throws;publicabstractvoidejbPassivate()throws;publicabstractvoidejbLoad()throws;publicabstractvoidejbStore()throws;publicabstractvoidejbRemove()throws;,所有实体构件必须实现EntityBean接口:,setEntityContext将当前实体构件实例与由容器管理的Context进行关联实例通过它获取所需的资源(事务服务、安全服务等)这种资源不特定于某一个标识unsetEntityContext用于终止一个实例的生命周期实例通过它释放setEntityContext获取的资源ejbActivate容器调用该方法从实例池中取出一个实例并为其赋予一个特定的实体对象标识实例不能使用该方法从数据库读取实体的状态必须用ejbLoad,ejbPassivate容器调用该方法将实例与实体对象标识进行分离并将实例放回实例池实例不能使用该方法向数据库存储实体的状态必须用ejbStoreejbLoad通知实例将缓存在实例变量中的实体状态与数据库中的实体状态同步该方法所处的事务由触发ejbLoad方法的业务方法所处的事务属性所决定ejbStore通知实例将数据库中的实体状态与缓存在实例变量中的实体状态同步该方法所处的事务由以前的ejbLoad或ejbCreate方法决定在ejbLoad或者ejbCreate方法与该ejbStore方法之间的所有方法都处于相同的事务中,2、容器向构件实现体提供的方法容器向构件实现体提供的方法主要表现为容器向构件实现体提供构件的上下文接口这是一个与构件实例一一对应的实体容器向构件实现体提供的具体方法包括:由EJBContext定义的基本方法由SessionContext定义的向会话构件提供的方法以及由EntityContext定义的向实体构件提供的方法,packagejavax.ejb;importjava.security.Identity;importjava.security.Principal;importjava.util.Properties;importjavax.transaction.UserTransaction;publicinterfaceEJBContextpublicabstractIdentitygetCallerIdentity();publicabstractPrincipalgetCallerPrincipal();publicabstractEJBHomegetEJBHome();publicabstractPropertiesgetEnvironment();publicabstractbooleangetRollbackOnly()throwsIllegalStateException;publicabstractUserTransactiongetUserTransaction()throwsIllegalStateException;publicabstractbooleanisCallerInRole(Strings);publicabstractbooleanisCallerInRole(Identityidentity);publicabstractvoidsetRollbackOnly()throwsIllegalStateException;,getEJBHome方法返回会话构件的homeinterfacegetCallerPrincipal方法返回java.security.Principal,标明会话构件实例调用者的EJB对象isCallerInRole方法用于测试会话构件实例的调用者是否具有某一特定角色setRollbackOnly方法用来标记当前事务,使其结束时必须卷回,只有容器管理的实例可以使用该方法getRollbackOnly方法用于测试当前事务是否必须卷回,只有容器管理的实例可以使用该方法getUserTransaction方法返回UserTransaction接口。实例可以用这个接口来划分事务和获取事务状态,只有构件管理的实例可以使用这个方法,packagejavax.ejb;publicinterfaceSessionContextextendsEJBContextpublicabstractEJBObjectgetEJBObject()throwsIllegalStateException;,packagejavax.ejb;publicinterfaceEntityContextextendsEJBContextpublicabstractEJBObjectgetEJBObject()throwsIllegalStateException;publicabstractObjectgetPrimaryKey()throwsIllegalStateException;,构件容器必须向会话构件提供SessionContext接口:,构件容器必须向实体构件提供EntityContext接口:,3、构件实现体与构件接口的方法,publicclassConverterEJBimplementsSessionBeanpublicdoubledollarToYen(doubledollars)returndollars*121.6000;publicdoubleyenToEuro(doubleyen)returnyen*0.0077;publicConverterEJB()publicvoidejbCreate()publicvoidejbRemove()publicvoidejbActivate()publicvoidejbPassivate()publicvoidsetSessionContext(SessionContextsc)仅声明实现了SessionBean接口,类型接口与实例接口呢?,其一:接口Converter扩展了接口EJBObject而EJBObject的功能是独立于具体构件的(由容器实现)类ConverterEJB不必实现接口EJBObject中的方法如果我们将类ConverterEJB声明为publicclassConverterEJBimplementsSessionBean,Converter当编译时会产生许多针对EJBObject中方法的错误其二:当构件需要调用其他构件时有时发出请求的构件需要将自身作为参数进行传递假如ConverterEJB需要向另外一个构件发出的一条消息中需要将自身作为参数进行传递编程人员可能想当然地写成someMethod(this)这在网络环境中却是行不通的必须根据前面介绍的方法getEJBObject从容器获取引用然后传递该引用,home接口中若干方法的实现,createmethodsfindermethodsRemovemethodshomemethodsejbCreateejbPostCreateejbFindejbRemoveejbHome,ejbCreate当客户利用构件的homeinterface中的create创建构件实例时容器调用构件实例的ejbCreate方法校验客户提供的参数向数据库插入表示实体对象的一条记录(例如:发出一句SQL语句insert)初始化实例变量每一个实体构件包含零或多个ejbCreate方法当构件的home接口未定义create方法时该实体构件不包含ejbCreate方法以限制客户对那些直接通过数据库插入而创建的实体的访问,ejbPostCreate对于每一个ejbCreate方法有一个对应的ejbPostCreate方法参数与之完全相同当容器调用完ejbCreate(.)方法后立即调用ejbPostCreate方法当调用ejbPostCreate方法时实体对象标识是可获得的例如,实例可以获取所关联的实体对象的remote接口并将其作为一个参数传送给另一个构件ejbPostCreate方法在与ejbCreate相同的事务(上下文)中执行,ejbFind当客户调用find方法时容器调用该方法当容器选择一个实例执行ejbFind方法时该实例处于pooled状态即未被分配给一个特定的实体对象标识当ejbFind方法结束时该实例被返回pooled状态ejbFind方法所处的事务由客户的find方法的事务属性决定ejbFind方法返回一个主键或者主键的集合,ejbRemove当客户调用remove方法时将从数据库中删除实体状态容器接受remove方法时调用ejbRemove方法将构件实例从ready状态转变为pooled状态容器在调用ejbRemove方法之前必须将实例的状态与数据库中的实体状态同步否则,首先调用ejbLoad方法ejbRemove所处的事务由客户的remove方法的事务属性决定该方法结束时,实例的状态等价于passivated实例的状态这意味着实例必须象ejbPassivate()那样释放所有的资源,ejbHomeHome方法是那些不特定于具体实体构件实例的业务逻辑例如:计算所有储户的总金额当客户调用home方法时容器调用任意一个实例上的该方法当容器选择一个实例执行ejbHome方法时该实例处于pooled状态即未被分配给一个特定的实体对象标识当ejbHome方法结束时该实例被返回pooled状态ejbHome方法所处的事务由客户的home方法的事务属性决定,四、会话构件实例的管理,会话构件,SessionSynchronization,SessionBean,Home,Remote,SessionContext,容器,1、有态构件实例的管理,有态构件是需要为多个方法调用保留话态的会话构件话态是特定于某一个具体客户的当存在大量的有态构件时由于系统资源(内存、数据库连接、网络连接等)有限因此需要将暂时不用的构件进行缓存(pooling)类似于传统操作系统面临的问题!基本算法:冻化:LRU(LeastRecentlyUsed)活化:Just-In-Time,3有态构件的生命周期是怎样的?,有态构件的状态转换图,会话构件实例产生于客户调用homeinterface的create()方法这引起container调用newInstance()、setSessionContext()、ejbCreate()并返回remote引用给客户实例进入methodready状态现在实例可以接受客户的business方法根据在deploymentdescriptor中的transactionattribute和客户调用的transactioncontext业务方法可以在transactioncontext中或未指定的transactioncontext中执行见图中的txmethod和non-txmethod,非事务方法在methodready状态下执行事务方法的调用使得实例被包含在一个事务中此时,容器会调用实例的afterBegin()实例会与事务结合直到事务结束客户此时调用的会话构件方法就会代理到构件实例上,如果请求提交事务事务服务会在提交前将请求告知容器容器调用beforeCompletion此时实例就应该将所有缓冲数据写到数据库如果请求卷回事务不用容器调用beforeCompletion就会达到卷回状态如果事务已经被标记为卷回容器不能调用beforeCompletion(实例也不会将缓冲写入数据库),事务完成后容器调用afterCompletion指定状态(提交或卷回)如果是卷回构件实例需要重置它的话态回到事务初始的值容器的缓冲算法可以决定从内存清除哪个构件实例(可能在每个方法后完成,或用LRU策略)容器调用ejbPassivate这些完成后,容器将实例的状态保存入辅存中会话构件只能在事务之间无事务时被冻化,当实例处于冻化状态时,容器可以在部署者指定的timeout时间到达后删除会话对象则针对该实例的所有对象引用和handle都无效如果客户调用一个已冻化实例的对象容器就会激活实例容器从辅存中恢复实例的状态并调用ejbActivate会话构件实例重新可以接受客户调用当客户调用remove时,容器向实例发出ejbRemove()当容器发现EJB对象的生命时间到达后也可以调用ejbRemove(),而不必客户调用remove,注意:如果会话构件类实现了SessionSynchronization接口不管直接或间接容器必须调用afterBeginbeforeCompletionafterCompletion方法如果没有实现SessionSynchronization就不必调用这些方法,2、无态构件实例的管理,无态会话构件是实例没有话态的会话构件因此各构件实例完全等价无态会话构件的Homeinterface必须有一个create方法没有参数并返回会话构件的remoteinterface并没有其他create方法容器可以代理客户调用到任何可用的实例上容器只需保留与现需服务客户数目等价的实例数缓存无态会话构件时(pooling)不需要对其进行冻化,无态构件的状态转换图,无态会话构件实例开始于容器调用newInstance();setSessionContext()和ejbCreate()容器可以在任何时间创建实例与客户调用create()方法没有任何关系无态会话构件实例此时可以代理客户的业务方法调用当容器不再需要实例时(通常容器想减少method-ready缓冲池中实例数的时候)容器调用ejbRemove(),实体构件三种状态:不存在缓存状态(Pooledstate)就绪状态(Readystate),EntityBean,Home,Remote,EntityContext,容器,四、实体构件实例的管理,1、BMP实体构件,当构件管理实体的持久性时构件提供者直接在实体构件中编写数据库访问语句(利用JDBC或SQL)在ejbCreate(.)ejbRemove()ejbFind()ejbLoad()ejbStore()业务方法等中都可能包含数据库访问语句数据访问调用可以直接编写在实体构件类中也可以被封装在数据访问类中以实体构件类附属类的形式作为构件的一部分其不足在于对异构数据库系统的适应性不足,BMP构件实例的状态转换图,l,不存在状态,l,池态,(,1,),newInstance(),setEntityContext(sc),(,2,),unsetEntityContext(),(,6,)业务方法,l,就绪状态,(,5,),ejbPassivate(),(,4,),ejbActivate(),(,3,),ejbHome,(.),(3),ejbFind(.,.),(,4,),ejbCreate(args),ejbPostCreate(args),(,5,),ejbRemove(),(,6,),ejbLoad(),(,6,),ejbStore(),4BMP构件的生命周期是怎样的?,实体构件的3种状态:不存在缓存状态(Pooledstate)实例不与一特定的实体对象标识关联就绪状态(Readystate)实例与一特定的实体对象标识关联,容器调用实体构件类的newinstance()方法创建构件实例它调用构件类的构造函数然后将该构件与实体context对象关联:setEntityContext()该操作发生于容器想增加实例池中的实例数目时,此时该实例可用于查找实体构件ejbFind如果容器认为目前实例过多可以通过unsetEntityContext删除构件实例,如果客户希望创建新数据库数据可以调用homeobject的create方法容器将从实例池中获取一个实例调用实例的ejbCreate实例进入就绪状态,构件实例处于就绪状态与一个特定的数据及Ejb对象关联如果其它实例也关联了相同的数据需要同步数据可以调用ejbLoad、ejbStore完成同步工作如果客户调用了remove操作容器将调用实例的ejbRemove方法低层的数据库数据将被删除实例与具体数据的关联自然消失实例回到实例池中,如果容器认为客户连接时间超时需要实例为其它客户服务时往往首先利用ejbStore将数据写回数据库然后利用ejbPassivate冻化实例实例回到实例池中如果容器需要再次分配实例可以调用实例的ejbActivate方法允许构件获取相应的资源然后调用ejbLoad向实例加载数据库数据,2、CMP构件,动因:BMP构件代码中与数据库相关的代码多BMP对特定数据存储系统的依赖性太大,解决方法:构件代码只负责与业务逻辑相关的工作以及所需资源的管理应用服务器负责机械性的数据访问过程,CMP构件实例的状态转换图,l,不存在状态,l,池态,(,1,),newInstance(),setEntityContext(sc),(,2,),unsetEntityContext(),(,6,)业务方法,l,就绪状态,(,5,),ejbPassivate(),(,4,),ejbActivate(),(,3,),ejbHome,(.),(3),ejbFind,ejbSelect,(,6,),ejbLoad(),(,6,),ejbStore(),(,6,),ejbSelect,ejbCreate,ejbPost,Create,(,4,),ejbRemove(),(,5,),ejbSelect构件提供者可以提供零或多个select方法一个select方法是一个不暴露给客户的特殊类型的查询方法通常与部署信息内的查询语句对应它是供构件提供者在业务方法内调用的抽象方法由应用服务器在组装、部署时刻产生具体方法ejbSelect方法所处的事务由调用该方法的业务方法所处的事务决定,BMP构件的实现,publicclassBMAccountBeanimplementsEntityBeanprotectedstaticDataSourcedataSource=null;protectedtransientEntityContextentityContext;protectedtransientbooleandirty;/Objectstatespublicintaccno;publicStringcustomer;publicdoublebalance;,3、BMP与CMP比较,publicvoidsetEntityContext(EntityContextctx)throwsRemoteExceptionentityContext=ctx;if(dataSource=null)ContextinitCtx=null;initCtx=newInitialContext();dataSource=(DataSource)initCtx.lookup(java:comp/env/jdbc/sample);publicvoidunsetEntityContext()entityContext=null;,publicAccountPKejbCreate(intaccno,Stringcustomer,doublebalance)throwsRemoteExceptionthis.accno=accno;this.customer=customer;this.balance=balance;Connectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(insertintoaccount(accno,customer,balance)values(?,?,?);stmt.setInt(1,accno);stmt.setString(2,customer);stmt.setDouble(3,balance);stmt.executeUpdate();catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();returnnewAccountPK(accno);,publicvoidejbPostCreate(intaccno,Stringcustomer,doublebalance)throwsRemoteException/nothingdonepublicvoidejbActivate()throwsRemoteException/nothingdonepublicvoidejbPassivate()throwsRemoteException/nothingdone,publicvoidejbLoad()throwsRemoteExceptionAccountPKpk=(AccountPK)entityContext.getPrimaryKey();Connectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(selectcustomer,balancefromaccountwhereaccno=?);stmt.setInt(1,pk.accno);ResultSetrs=stmt.executeQuery();accno=pk.accno;customer=rs.getString(customer);balance=rs.getDouble(balance);catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();,publicvoidejbStore()throwsRemoteExceptionConnectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(updateaccountsetcustomer=?,balance=?whereaccno=?);stmt.setString(1,customer);stmt.setDouble(2,balance);stmt.setInt(3,accno);stmt.executeUpdate();catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();,publicvoidejbRemove()throwsRemoteException,RemoveExceptionAccountPKpk=(AccountPK)entityContext.getPrimaryKey();Connectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(deletefromaccountwhereaccno=?);stmt.setInt(1,pk.accno);stmt.executeUpdate();catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();,publicAccountPKejbFindByPrimaryKey(AccountPKpk)throwsObjectNotFoundException,RemoteExceptionConnectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(selectaccnofromaccountwhereaccno=?);stmt.setInt(1,pk.accno);ResultSetrs=stmt.executeQuery();if(rs.next()=false)thrownewObjectNotFoundException();catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();returnpk;,publicAccountPKejbFindByNumber(intaccno)throwsObjectNotFoundException,RemoteExceptionConnectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(selectaccnofromaccountwhereaccno=?);stmt.setInt(1,accno);ResultSetrs=stmt.executeQuery();if(rs.next()=false)thrownewObjectNotFoundException();catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();returnnewAccountPK(accno);,publicEnumerationejbFindAllAccounts()throwsObjectNotFoundException,RemoteExceptionVectorv=newVector();Connectionconn=null;PreparedStatementstmt=null;tryconn=dataSource.getConnection();stmt=conn.prepareStatement(selectaccnofromaccount);ResultSetrs=stmt.executeQuery();doAccountPKpk=newAccountPK(rs.getInt(accno);v.addElement(pk);while(rs.next();catchif(stmt!=null)stmt.close();if(conn!=null)conn.close();returnv.elements();,publicintgetNumber()throwsRemoteExceptionreturnaccno;publicStringgetCustomer()throwsRemoteExceptionreturncustomer;publicvoidsetCustomer(Stringcustomer)throwsRemoteExceptionthis.customer=customer;setDirty(true);publicdoublegetBalance()throwsRemoteExceptionreturnbalance;,publicdoubledeposit(doubleamount)throwsRemoteExceptionbalance+=amount;setDirty(true);returnbalance;publicdoublewithdraw(doubleamount)throwsRemoteExceptionif(balanceamount)thrownewRemoteException(Noenoughbalance);balance-=amount;setDirty(true);returnbalance;privatevoidsetDirty(booleanflag)dirty=flag;publicbooleanisModified()returndirty;,/transfermonySystem.out.println(“transfer100froma2toa1);doubleamount=100.00;a2.withdraw(amount);a1.deposit(amount);/listallaccountsSystem.out.println(Gettingthenewlistofaccountsindatabase);Enumerationlist=home.findAllAccounts();while(list.hasMoreElements()Accountac=(Account)list.nextElement();System.out.print(ac.getNumber()+);System.out.flush();System.out.print(ac.getCustomer()+);System.out.flush();System.out.print(ac.getBalance();System.out.println();,(2)CMP构件的实现,publicclassCMAccountBeanimplementsEntityBeanprotectedEntityContextctx;protectedbooleandirty;publicintaccno;publicStringcustomer;publicdoublebalance;publicvoidejbCreate(intaccno,Stringcustomer,doublebalance)this.accno=accno;this.customer=customer;this.balance=balance;publicvoidejbPostCreate(intaccno,Stringcustomer,doublebalance)/nothingdone,publicvoidejbActivate()throwsRemoteException/nothingdonepublicvoidejbPassivate()throwsRemoteException/nothingdonepublicvoidejbLoad()throwsRemoteExceptionsetDirty(false);publicvoidejbStore()throwsRemoteExceptionsetDirty(false);publicvoidejbRemove()throwsRemoveException,RemoteException/nothingdonepublicvoidsetEntityContext(EntityContextctx)throwsRemoteExceptionthis.ctx=ctx;publicvoidunsetEntityContext()this.ctx=null;,publicintgetNumber()throwsRemoteExceptionreturnaccno;publicStringgetCustomer()throwsRemoteExceptionreturncustomer;publicvoidsetCustomer(Stringcustomer)throwsRemoteExceptionthis.customer=customer;setDirty(true);publicdoublegetBalance()throwsRemoteExceptionreturnbalance;publicdoubledeposit(doubleamount)throwsRemoteExceptionbalance+=amount;setDirty(true);returnbalance;,publicdoublewithdraw(doubleamount)throwsRemoteExceptionif(balanceamount)thrownewRemoteException(Noenoughbalance);balance-=amount;setDirty(true);returnbalance;privatevoidsetDirty(booleanflag)dirty=flag;publicbooleanisModified()returndirty;,思考题,1构件运行环境主要关心哪些问题?2EJB构件与构件运行环境之间的接口有哪些?3有态构件的生命周期是怎样的?4BMP构件的生命周期是怎样的?,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!