Weblogic EJB 学习W记 | ||
littleboys 原创 (参与分:47498Q专家分Q?30) 发表Q?003-06-18 11:16 版本Q?.0 阅读Q?B>12529? |
EJB 学习W记 1、ejb 基础知识 Q?Q?nbsp;无状态会话bean 不保存客h的会话状?BR> 优点Q用小量的实例卛_满大量的客戗每个实例都没有标识Q相互之间是{h的?BR> {?的无状态会话beanQ?nbsp; 多次和一ơ调用的l果和效应相同?BR> 在集中可以负蝲均衡 a 机器p|Q可以在b机器上重?BR> 非等?的无状态会话beanQ?nbsp;如:计数?BR> 不能自动因故障而进行切换?BR>Q?Q?nbsp;有状态会话bean 保存客户机的会话状?BR> 特点Q?nbsp;在有会话状态会话的bean例子中,出纳员的数量{于zd的顾客的数量Q这可以化编E模?BR> weblogic 通过内存复制技?nbsp;在集中q行负蝲均衡 内存复制技术: 每个有会话状态的bean实例都将存储在两个服务器的内存中Q一个服务器作ؓL务器Q另一个作助服务器?BR> 如果d败,辅助变ؓ主,然后自动选择别的可用的服务器作ؓ辅助?BR> 遗憾Q?nbsp;很难在servlet 和jsp中用好有状态会话bean。可能会发生q发现象Q生RemoteException weblogic ?lt;allow-concurrent-calls> 可以锁Mq发的调用?BR> 同步Q?nbsp;可以有选择地实?nbsp;javax.ejb.SessionSynchronization接口 afeterBegin() //q入事务?BR> beforeCompletion() //提交事务?用于提交前把~存的数据写到数据库? afterCompletion() //提交事务?用于释放׃n资源或者更C务提交和l止斚w的统计信? 会话bean通过?nbsp;SessionContext 对象中的 getUserTransaction() Ҏ,取得对UserTransaction的应?BR> 通常 SessionContext 被存攑֜成员变量?BR> ** C是在调用ejb.create()Ҏ前调?nbsp;setUserTransaction() Ҏ 利用?nbsp;UserTransaction 的引用会话可以?nbsp;begin() 、commit()、rollback() Ҏ界定一个事? Q?Q?nbsp;实体 beanQ?nbsp; 它有一个主健作为唯一的标识符 l成部分: 由本地接口、远E接口、beancR主健类和配|描q器l成?BR> 本地接口Q?BR> 扩展了javax.ejb.EJBHome接口Q包括createQ)、removeQ)、finder 和home{方?BR> 1)createQ)Ҏ调用beancM的ejbCreateQ)Ҏ。相当于数据的insert Ҏ?BR> 2)removeQ)Ҏ相当于数据库的delete操作?BR> 3)finderQ)ҎQ客户能够查询和接收满x询条件的实体bean的引用。每个实体bean的本地接口中都必?BR> 有一个findByPrimaryKey() Ҏ 4)home ҎQ类g无状态会话bean?BR> dc: 实体bean必须包括一个主健类Q主健类用于标识实体bean实例Q而且实体bean数据cd必须是唯一的?BR> dcd以是java的基本类型String Integer 也可以是用户自定义的?BR> 也可以是多个字段的主健的复合d?BR> bean cdbean的上下文环境Q?BR> 实现javax.ejb.EJBObject 接口,其中包含业务Ҏ的语法格式定? bean cdCjavax.ejb.EntityBean接口,同javax.ejb.SessionBean接口一?EntityBean 接口包含了EJB 容器调用bean实例的语法格? 在bean的构造器执行之后,立即调用setEntityContext() Ҏ,同时把bean实例的EntityContext 传递给? beancdChomeҎ和远E接口中的业务方?homeҎ是针对匿名实例的Ҏ不应使用有关的主健? 分ؓQ?BR> 容器理持久性(ContainerQManagerd PersistenceQCMP 特点Q?nbsp;EJB 容器自动生成Q用于把实体bean的数据写入到数据库中?BR> 优点Q?nbsp;bean作者可以避免编写实体bean与关pL据库数据讉K斚w的代码。cmp自动处理这一q程?BR> 个? 每一个cmp 实体bean 都有一l容器管理的字段,q些字段存储在数据库,q可从中加蝲.通常,每个容器理的字D都对应?BR> 关系数据库中的一个列. 容器理的每个字D必dejb-jar.xml中定?q容器能够把容器管理的字段与beancM的set和getҎq行匚w比较. 另外,bean作者可以增加另外一个cmp配置描述文g weblogic-cmp-rdbms.xml,其中包含数据库表名和每个容器理的字 D和相应的数据列的映? bean理持久性(BeanQManagerd Persistence Q?nbsp;BMP 特点Q?nbsp;在bmp实体中,bean作者需要自q写数据库讉K代码Q也是~写JDBC代码Q插入、删除和查询数据库中的实体bean数据?BR> 优点Q?nbsp;可以让bean的作者完全灵zȝ处理实体bean的持久性数据,因ؓ作者需要写数据讉K的代码,他几乎可以用Q何持久性存 储方式ejb2.0 cmp提供实体bean之间的标准关pL,使容器能自动理业务对象之间的交互?BR> cmp拥有更多的访问控Ӟ因此cmp比bmp有较好的性能?BR> Q?Q?nbsp;消息 bean 把JMS 和EJB 成功l合在一P集成的结?BR> 特点Q客h不需要调用消息bean 相反Q?nbsp;客户机只需要发一个消息给jMS目的?BR> 在消息到达以后,消息bean的onmessageQ)Ҏ被调用Q以处理q个消息?BR> 消息bean用于在服务器中执行异步操作?BR> 2。EJB l成 Q?Q远E接?BR> public interface HelloWord extents EJBObject ?BR> //EJBObject 接口Ҏ EJBHome getEJBHome() throws RemoteException; Object getPrimaryKey() throws RemoteException; void remove() throws RemoteException, RemoveException; Handle getHandle() throws RemoteException; boolean isIdentical(EJBObject ejbObject) throws RemoteException; ?BR>Q?Q本地接?BR> 本地接口是ejb工厂Q客h可以使用本地接口创徏、找出和删除ejb实例。只需写本地接口中的方法的语法调用格式 public class HelloWorldHome extends EJBHome ?BR> //EJBHome 接口Ҏ void remove(Handle handle) throws RemoteException, RemoveException; void remove(Object o) throws RemoteException, RemoveException; EJBMetaData getEJBMetaData() throws RemoteException; HomeHandle getHomeHandle() throws RemoteException; // Home public HelloWorld create() throws CreateException, RemoteException; ?BR> Q?Qbean c?BR> public class HelloWorldBean implements SessionBean ?BR> // SessionBean 中的Ҏ public void setSessionContext(SessionContext sessionContext) /**调用ơ方法会话结?/ public void ejbRemove() //ejb通过待命和活动的机制Q管理一l正在工作的有状态会话bean实例 /**zd*/ public void ejbActivate() /**待命*/ public void ejbPassivate() // beanc?BR> // 每个home 的create Ҏ对应一个ejbCreateQ)Ҏ // 有会话状态有很多不同版本的createQ)Ҏ。而create Ҏ必须有ejbCreateQ)Ҏ与之一一对应 public void ejbCreate() ?BR> 不要在ejbcMcM实现q程接口 3. EJB 配置描述?BR>Q?QejbQjar.xml <ejb-jar> (注释) <enterprise-beans> <session> <ejb-name>HelloWorldQejbnameQ?lt;/ejb-name> <home>com.dhc.helloworld.HelloWorldHomeQ本地接口类Q?lt;/home> <remote>com.dhc.helloworld.HelloWorldQ远E接口类Q?lt;/remote> <ejb-class>com.dhc.helloworld.HelloWorldBeanQbeanc)</ejb-class> <session-type>StatelessQ无状态会话)</session-type> <transaction-type>BeanQbean理的事务)</transaction-type> </session> </enterprise-beans> <container-transaction> <method> <ejb-name>ShoppingCartEjb</ejb-name> <method-name>*Q说明ShoppingCartEjb的默认事务属性指定ؓRequiredQ?lt;/method-name> </method> <trans-attribute>RequiredQ容器管理的事务使用的属?nbsp;Nerver、NotSupported 、Supports、Mandatory、Required、RequiredNewQ?lt;/trans-attribute> </container-transaction> </ejb-jar> Q?Qweblogic-ejb-jar.xml (注释) <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>HelloWorldQejb名称Q?lt;/ejb-name> <jndi-name>HelloWorldEJBQjndi名称Q?lt;/jndi-name> <max-bean-in-freepool>10Q限制不会有过10个无状态会话beanq发q行Q?lt;/max-bean-in-freepool> <max-bean-in-cache>10Q放到内存缓存中的有状态会话bean的最大数量)</max-bean-in-cache> </weblogic-enterprise-bean> </weblogic-ejb-jar> 4 . 建立ejb 档案文g com/dhc/helloworld/QpackageQ?BR>com/dhc/helloworld/HelloWorldQ远E接口) com/dhc/helloworld/HelloWorldHomeQ本地接口) com/dhc/helloworld/HelloWorldBeanQbeanc) META-INF META-INF/ejbQjar.xmlQ配|描q器Q?BR>META-INF/weblogic-ejb-jar.xmlQweblogic服务器配|描q器Q?BR> 说明Q?nbsp;META-INF 必须为大?BR> 5 . 容器理的事?BR>Nerver : 不参与事?如果参与产生RemoteException NotSupported: 不能参与 Supports: 如果调用者正在参与事?相应的EJB调用也可以参与事?否则不能 Mandatory 如果调用者有一个事?相应的EJB可以参与事务,否则,TransactionRequiredException Required 如果调用者有一个事?相应的EJB可以参与事务,否则,容器在调用相应的EJB之前,开始一个事? 当方法调用完成以?x交该事务. RequiresNew 在调用相应的EJB之前,开始一个新的事?当方法调用返回时,x交这个事? 6、ejb 引用 在ejbQjar.xml <ejb-ref> <description> an EJB reference to the Widget EJB(描述)</description> <ejb-ref-name>ejb/WidgetEJB</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <home>com.dhc.WidgetHome</home> <remote>com.dhc.Widget</remote> </ejb-ref> ?nbsp;weblogic-ejb-jar.xml <ejb-reference-description> <ejb-ref-name>ejb/WidgeEJB</ejb-ref-name> <jndi-name>DeployedWidge</jndi-name> </ejb-reference-description> E序 Content ctx = new InitialContent(); Object h = ctx.lookup("java:/comp/env/ejb"); //环境变量是只ȝ,而且是当前ejb的本地变? WidgetHome home = (WidgetHome)PortableRemoteObject.narrow(h,WidgeHome.class); 7. 资源理器的引用 定义资源理的引?BR>例子Q?nbsp;建立 jdbc、DBPool与JDBC数据源的映射 在ejbQjar.xml <resource-ref> <description>(描述)</description> <res-ref-name>jdbc/BDPool</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> ?nbsp;weblogic-ejb-jar.xml <resource-description> <res-ref-name>jdbc/DBPool</res-ref-name> <jndi-name>DBPool</jndi-name> </resource-description> config.xml <JDBCTxDataSource name="DBPool" Targets="myserver" JDDIName="DBPool" (jndi名称) PoolName ="DevelopmentPool" /> 引用的优?BR>我们用大量的映射和配|,才徏立了资源理器的引用Q但是还是很值得的?BR>以ؓ便于部v人员重新配置应用而不需要修改实际的beancM码。甚至也不需要修改ejb的配|描q器 java bean 代码 Content ctx = new InitialContent(); DataSource dataSource = (DataSource)ctx.lookup("java:/comp/env/jdbc/DBPool"); 8 . 句柄Q?nbsp;作ؓ一个串行化的对象,句柄中封装了_的信息,以便重徏对EJBObject的引用?BR>句柄可用于在两个怺合作的进E中传递EJBObject的引用。接受进E即可从句柄中取得EJBObject的引用?BR> Z取得句柄Q可以调用EJBObject接口的getHandleQ)ҎQ返回一个Handle实例 Z重徏EJBObject 引用。可以用Handle 接口的getEJBObjectQ)Ҏ?BR> 例子Q?BR> HelloWorld hw = home.create(); javax.ejb.Handle handle = hw.getHandle(); HelloWorld helloworld = (HelloWorld)PortableRemoteObject.narrow(handle.getEJBObject(),HelloWorld.class); HomeHandle: cMhandle Q但不能用于引用EJBObject HomeHandle 包含_的信息,可以重徏EJBHomeQ)的引用?BR> 差异Q?BR> 是调?nbsp;getHomeHandleQ)Ҏ 和getEJBHomeQ)Ҏ 例子片断Q?BR> Content ctx Q?nbsp;new InitialContext(); Object h = ctx.lookup("HelloWorldEJB"); HelloWorldHome home = (HelloWorldHome)PortableRemoteObject.narrow(h,HelloWorldHome.class); HomeHandle homehandle = home.getHomeHandle(); Object nh = homehandle.getEJBHome(); HelloWorldHome newHomeReference = (HelloWorldHome)PortableRemoteObject.narrow(nh,HelloWorldHome.class); 优点: 他们可以自动的存储重建引用所需的信?BR> 9.使用事务的技? (1) 一个事务不要涉及太多的操作. (2) 容器理和bean理的事?BR> 事务既耗费应用服务器中的资?又耗费数据库资?所以事务越短越? 量使用容器理事务而不要采用bean理事务的方? (3) ejb遇到错误,需要强制事务回? 使用EJBObject.setRollbackOnly(); (4) 不能让事务涉及web层和表示逻辑 (5) 企业应用中不应当选用supports 事务属?因ؓ只有调用者开始一个事务后,ejb才能在事务中q行. |