2。EJB 组成
(1)远程接口
public interface HelloWord extents EJBObject
{
//EJBObject 接口方法
EJBHome getEJBHome() throws RemoteException; Object getPrimaryKey() throws RemoteException; void remove() throws RemoteException, RemoveException; Handle getHandle() throws RemoteException; boolean isIdentical(EJBObject ejbObject) throws RemoteException;
}
(2)本地接口
本地接口是ejb工厂,客户机可以使用本地接口创建、找出和删除ejb实例。只需写本地接口中的方法的语法调用格式
public class HelloWorldHome extends EJBHome
{
//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;
}(3)bean 类
public class HelloWorldBean implements SessionBean
{
// SessionBean 中的方法
public void setSessionContext(SessionContext sessionContext)
/**调用次方法会话结束*/
public void ejbRemove()
//ejb通过待命和活动的机制,管理一组正在工作的有状态会话bean实例
/**活动*/
public void ejbActivate()
/**待命*/
public void ejbPassivate()
// bean类
// 每个home 的create 方法对应一个ejbCreate()方法
// 有会话状态有很多不同版本的create()方法。而create 方法必须有ejbCreate()方法与之一一对应
public void ejbCreate()
} 不要在ejb类中类中实现远程接口
(1)远程接口
public interface HelloWord extents EJBObject
{
//EJBObject 接口方法
EJBHome getEJBHome() throws RemoteException; Object getPrimaryKey() throws RemoteException; void remove() throws RemoteException, RemoveException; Handle getHandle() throws RemoteException; boolean isIdentical(EJBObject ejbObject) throws RemoteException;
}
(2)本地接口
本地接口是ejb工厂,客户机可以使用本地接口创建、找出和删除ejb实例。只需写本地接口中的方法的语法调用格式
public class HelloWorldHome extends EJBHome
{
//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;
}(3)bean 类
public class HelloWorldBean implements SessionBean
{
// SessionBean 中的方法
public void setSessionContext(SessionContext sessionContext)
/**调用次方法会话结束*/
public void ejbRemove()
//ejb通过待命和活动的机制,管理一组正在工作的有状态会话bean实例
/**活动*/
public void ejbActivate()
/**待命*/
public void ejbPassivate()
// bean类
// 每个home 的create 方法对应一个ejbCreate()方法
// 有会话状态有很多不同版本的create()方法。而create 方法必须有ejbCreate()方法与之一一对应
public void ejbCreate()
} 不要在ejb类中类中实现远程接口
解决方案 »
- 菜鸟问题之四:页面变量与小脚本变量区别?
- 简单的注册,MD5加密
- 两年前彻底摒弃了ssh ,刚跳到新公司,有回归了ssh,是退步还是进步。。。
- struts2绑定select的问题
- 如何用JS获取iframe内文件的值?高分求解
- jsp里FCKeditor出错!
- 作用了过滤中文乱码的类后,回车不见了。怎么办啊?
- 关于系统学习JAVA--老鸟,小鸟们进来说说看
- 关于设计数据库表时的字段问题?
- 帮我看看这段代码,关于不能同时显示数据库的多条字段的中文记录的问题,急!!!!
- 将mysql中的中文内容输出到html页面出问题了???
- 请大家帮帮忙,看看我的程序什么地方不对,谢谢了,在线等,我是jsp的初学者
(1)ejb-jar.xml
<ejb-jar> (注释)
<enterprise-beans>
<session>
<ejb-name>HelloWorld(ejbname)</ejb-name>
<home>com.dhc.helloworld.HelloWorldHome(本地接口类)</home>
<remote>com.dhc.helloworld.HelloWorld(远程接口类)</remote>
<ejb-class>com.dhc.helloworld.HelloWorldBean(bean类)</ejb-class>
<session-type>Stateless(无状态会话)</session-type>
<transaction-type>Bean(bean管理的事务)</transaction-type>
</session>
</enterprise-beans>
<container-transaction>
<method>
<ejb-name>ShoppingCartEjb</ejb-name>
<method-name>*(说明ShoppingCartEjb的默认事务属性指定为Required)</method-name>
</method>
<trans-attribute>Required(容器管理的事务使用的属性 Nerver、NotSupported
、Supports、Mandatory、Required、RequiredNew)</trans-attribute>
</container-transaction>
</ejb-jar>
(2)weblogic-ejb-jar.xml (注释)
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>HelloWorld(ejb名称)</ejb-name>
<jndi-name>HelloWorldEJB(jndi名称)</jndi-name>
<max-bean-in-freepool>10(限制不会有超过10个无状态会话bean并发运行)</max-bean-in-freepool>
<max-bean-in-cache>10(放到内存缓存中的有状态会话bean的最大数量)</max-bean-in-cache>
</weblogic-enterprise-bean>
</weblogic-ejb-jar> 4 . 建立ejb 档案文件
com/dhc/helloworld/(package)
com/dhc/helloworld/HelloWorld(远程接口)
com/dhc/helloworld/HelloWorldHome(本地接口)
com/dhc/helloworld/HelloWorldBean(bean类)
META-INF
META-INF/ejb-jar.xml(配置描述器)
META-INF/weblogic-ejb-jar.xml(weblogic服务器配置描述器)说明: META-INF 必须为大写5 . 容器管理的事务
Nerver : 不参与事务,如果参与产生RemoteException
NotSupported: 不能参与
Supports: 如果调用者正在参与事务,相应的EJB调用也可以参与事务,否则不能
Mandatory 如果调用者有一个事务,相应的EJB可以参与事务,否则,TransactionRequiredException
Required 如果调用者有一个事务,相应的EJB可以参与事务,否则,容器将在调用相应的EJB之前,开始一个事务.
当方法调用完成以后,即提交该事务.
RequiresNew 在调用相应的EJB之前,开始一个新的事务,当方法调用返回时,即提交这个事务.
<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>在 weblogic-ejb-jar.xml
<ejb-reference-description>
<ejb-ref-name>ejb/WidgeEJB</ejb-ref-name>
<jndi-name>DeployedWidge</jndi-name>
</ejb-reference-description>程序
Content ctx = new InitialContent();
Object h = ctx.lookup("java:/comp/env/ejb"); //环境变量是只读的,而且是当前ejb的本地变量.
WidgetHome home = (WidgetHome)PortableRemoteObject.narrow(h,WidgeHome.class);7. 资源管理器的引用
定义资源管理的引用
例子: 建立 jdbc、DBPool与JDBC数据源的映射
在ejb-jar.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>在 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"
/>引用的优点
我们用大量的映射和配置,才建立了资源管理器的引用,但是还是很值得的。
以为便于部署人员重新配置应用而不需要修改实际的bean类代码。甚至也不需要修改ejb的配置描述器
java bean 代码Content ctx = new InitialContent();
DataSource dataSource = (DataSource)ctx.lookup("java:/comp/env/jdbc/DBPool");8 . 句柄: 作为一个串行化的对象,句柄中封装了足够的信息,以便重建对EJBObject的引用。
句柄可用于在两个相互合作的进程中传递EJBObject的引用。接受进程即可从句柄中取得EJBObject的引用。为了取得句柄,可以调用EJBObject接口的getHandle()方法,返回一个Handle实例
为了重建EJBObject 引用。可以使用Handle 接口的getEJBObject()方法。例子:
HelloWorld hw = home.create();
javax.ejb.Handle handle = hw.getHandle();
HelloWorld helloworld = (HelloWorld)PortableRemoteObject.narrow(handle.getEJBObject(),HelloWorld.class);
HomeHandle:
类似handle ,但不能用于引用EJBObject
HomeHandle 包含足够的信息,可以重建EJBHome()的引用。
差异:
是调用 getHomeHandle()方法 和getEJBHome()方法
例子片断:
Content ctx = 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);优点:
他们可以自动的存储重建引用所需的信息9.使用事务的技巧:
(1) 一个事务不要涉及太多的操作.
(2) 容器管理和bean管理的事务
事务既耗费应用服务器中的资源,又耗费数据库资源,所以事务越短越好.
尽量使用容器管理事务而不要采用bean管理事务的方式.
(3) ejb遇到错误,需要强制事务回滚. 使用EJBObject.setRollbackOnly();
(4) 不能让事务涉及web层和表示逻辑
(5) 企业应用中不应当选用supports 事务属性,因为只有调用者开始一个事务后,ejb才能在事务中运行.
1. 怎样开发主健类
ejb的主健类主要用做持久存储和ejb容器中的唯一标识符.
通常主健类的字段直接映射到数据库中的主健字段.
如果主健只是由单个实体bean字段组成.且其数据类型是基本的java类.如string,则bean作者不必开发自定义的主健类.
只需要在配置描述器中指定类的名字和主健字段即可如果把主健映射到一个用户定义的类型,或者映射到多个字段,则bean的作者必须写出自定义的主健类.主健类必须实现 java.io.serializable,而且包含主健字段.对于cmp,字段名必须匹配实体bean中的相应的主健字段名,这将使ejb容器能够把适当的cmp字段赋值到主健类中的相应字段中.2. 实现hashcode()方法
hashcode() 方法的实现原理是,利用主健字段,经适的处理后,生成并返回一个整数. 这个生成的整数称为散列码,用作表格的索引.
对于一个给定的主健,hashcode()方法的返回值应当总是一样的. 常见做法: 执行"异或" 操作.3. 实现 equals() 方法
正确地实现equals()方法也需要一定的技巧. 任何equals() 方法的第一行都应当检查传递进来的引用是否是"this", 检查equals()
方法是否是针对自己的调用. 通常做法: 当容器有一个主健对象时,她要检查这个主健对象是否已经存在于数据结构中.接着,equals() 方法需要检查传递进来的主健类的类型. 如果主健类是中继类(final),可以使用instanceof 进行简单的检查.
否则,传递进来的参数也许是主健类的子类.在这种情况下,equals() 方法必须使用getClass.equals, 以确保类的类型是匹配的建议主健类采用终极类. (instanceof 效率要高一些)最后,equals() 方法需要需要比较传递进来的对象的所有值. 如果所有值是相同的,说明对象也是相同的
注意: 要先比较散列码.4 实体bean的继承和异构
实体bean 可以利用java的继承和异构的特性.5. 继承的限制
尽管ejb 规范允许组件之间的继承,但夜游一些细微的规则限制了怎样设计和实现一个继承的ejb.
ejb的规则要求,本地接口的create() 方法返回的远程接口不能是一个子类,也不能是超类. 实体bean 的ejbreate() 方法也
必须返回主健类型,也不能是一个子类,也不能是超类.
类似的findByPrimaryKey()方法必须使用主健类型作为参数返回远程接口.
这些要求限制了bean作者对继承的实现.6. 继承和异构的设计模式注意: 具有继承和异构特性的实体bean,很重要一点就是要确定一般情况下究竟都需要使用哪一些属性.7 . 接口的继承通过bean类的继承性,bean作者只需要在一个地方实现业务方法,其它实体bean就可以共享类中的方法了.8 使用多个bean类
为本地和远程接口创建一个基本接口,不是达到异构共享的唯一方法. 另一个常见的做法是
使用等同的本地和远程接口,但采用不同的bean类实现其中的业务方法.
这种做法类似于使用一个具有若干不同实现的接口.
好处: 客户不知道或根本不管正在使用哪一种实现,客户机只对接口进行操作.9. 实体bean 与锁 实体bean 不是可重入的或多线程的组件,每个实体bean实例也没有多线程控制的能力。
一次实体bean 类中的方法也不是同步化的。
实体bean实例不能是多线程的,所以ejb容器必须串行地执行所有的容器方法和业务方法。
这意味着当业务方法正在执行时,ejb容器不能再调用其它方法,比如 ejbPassivate()方法。 并发控制:
一种做法是对每一个事务都激活实体bean实例。同过数据库的访问锁的方式进行并发处理。
一种方法是,每一个主健只保持一个实体bean实例,这样一次只有一个事务可以访问实体bean。一旦
前一个事务提交或回滚,才允许另一个事务使用这个实体bean实例。
并发控制策略:
数据库并发控制:
除非特别情况,应尽量使用默认的数据库并发控制。
排它性并发控制: