在EJB领域中,客户q没有直接调用EJB实例Q它们仅仅调用了EJB对象代理。借助于Home对象能够生成EJB对象。因此,对于定义在EJB BeancM的各个ejbCreate()ҎQ在Home接口中也存在对象的create()Ҏ。当客户调用Home对象的create()ҎӞ容器把调用h委派lejbCreate()Ҏ?br /> 开发者可以通过多种方式查找实体Bean.需要在实体Bean的Home接口中列丑ևq些查找Ҏ。我们称q些Ҏ?finder"Ҏ。除了暴露创建、销毁实体Bean实例的方法外QHome接口q需暴露finderҎ。这是实体Bean的Home接口同其他EJBcd中的Home接口的最明显区别?/p>
实体上下文,所有的EJBlg都存在上下文对象供组件访问到容器环境使用。这些上下文对象含有EJB容器讄的环境信息。因此EJBlg能够讉KC下文Q从而获取各U信息,比如事务Q安全性信息。对于实体Bean而言Q存在javax.ejb.EntityContext上下文接口。它l承自EJBContext
public interface javax.ejb.EntityContext extends javax.ejb.EJBContext{
public javax.ejb.EJBLocalObject getEJBLocalObject();
public javax.ejb.EJBObject getEJBObject();
public java.lang.Object getPrimarykey();
}
通过调用getEJBObject()ҎQ当前客戯够获得某实体Bean实例对应的EJB对象。客戯用的是EJB对象Q而不是实体Bean实例本n。因此,客户能够在应用中引用q回的EJB对象?br />
实体Bean实例对应的主键可以通过getPrimaryKey()Ҏ获得。主键唯一标识某实体Bean实例。当实体Bean实例存储到存储源中时Q可以用主键获得单个实体Bean实例。由于在RDBMS中也存在主键Q因此主键能够唯一标识某个实体Bean实例?/p>
Z满大量q发客户讉K同一数据的要求,架构师需要借助于实体Bean设计出高性能的访问系l。如下给ZU解x案:允许多个客户׃n同一实体Bean实例。因此,实体Bean实例能够同时服务多个客户。尽表面上看是可行的,但是对于EJB而言Q这是行不通的。原因有亮点Q其一Qؓ实现实体Bean实例服务多个q发客户Q必M证实体Bean实例是线E安全的Q开发线E安全的代码q不是一件容易的工作Q而且l常会出C堆错我。其二,底层事务pȝ几乎不可能控制多个线E的q发执行Q事务往往同具体的U程l定在一赗因此,Z上述理由Q单个实体Bean实例只能够在单线E环境中q行。对于所有的EJBlg而言Q包括会话Bean、消息驱动Bean、实体BeanQ它们都是以单线E方式运行的?br />
当然Q强制要求各个实体Bean实例只能同时服务单个客户Q将引入性能瓉。由于实例以单线E方式运行,客户需要排队等候实体Bean实例Q从而获得对实体Bean实例的调用,q对于大型企业应用而言Q是不允许出现的
Z提供pȝ性能QEJB容器会实例化同一实体Bean的多个实例。这使得多个客户能够q发同不同实体Bean实例q行交互Q而这些实体Bean实例代表了同一RDBMS数据。事实上Q这是EJB容器的运行行为。因此,客户再也不用排队{候实体Bean实例Q因为存在多个实体Bean实例了?br />
一旦多个实体Bean实例代表了同一RDBMS数据Q则引入了另外一个问题:数据瘫痪。如果多个实体Bean实例代表的数据是通过~存理的,则需要在内存中拷贝多分缓存中的数据。显Ӟ某些~存中的数据变得陈旧,因此会出现很多过期的数据?br />
Z实现实体Bean实例的缓存一致性,各个实体Bean实例必须同底层存储元q行同步。EJB容器通过调用ejbLoad(),ejbStore()Ҏ同步q些实体Bean实例?br />
至于实体Bean实例同底层RDBMS数据的同步频率,则取决于事务。事务将各个客户h隔离h。借助于事务实现数据同步?/p>
EJB容器提供的实例池是很有意义的。当Ӟq不是只有实体Bean才存在实例池。在实体Bean实例重新分配l不同EJB对象Ӟ会存在一些问题,q要求容器去解决。比如当实体Bean实例被指定给EJB对象Ӟ它可能还持有资源(比如Socketq接)。如果将实体Bean实例攄在实例池中,Socketq接不在需要。因此ؓ实现资源的获取和释放Q实体Bean的Beanc需要实现如?个回调方法:
1、ejbActivate().在将实体Bean实例从实例池中取出来ӞEJB容器会自动调用它。该q程UC为激zR进而,EJB容器会将实体Bean实例分配l某EJB对象Qƈ同时获得主键对象。在执行ejbActivate()Ҏ期间Q实例需要获得所需的资源,比如Socke,否则Q在实体Bean实例分配l某EJB对象Ӟ无法对资源进行操作?br />
2、ejbPassivate().在将实体Bean实例攄到实例池中时QEJB容器会调用它。注意,它也是回调方法。这一q程UC为挂赗进而,EJB容器需要从某EJB对象中取回分配于它的实体Bean实例Qƈ实例的主键对象也收回。在执行ejbPassivate()Ҏ期间Q需要释放ejbActivate()执行期间获得的相兌源,比如QSocket.
一旦实体Bean实例被挂P不但要释攑֮持有的资源,q将实例的状态信息保存v来。因此,实体Bean实例最新的状态信息可以从RDBMS中找C。ؓ了保存实体Bean实例的域信息到RDBMS中,容器要在挂v实例前调用ejbStore()Ҏ。类似的Q一旦实体Bean被激z,不但要获得所需的资源,q要从RDBMS装蝲最新的数据Qؓ了完成数据的dQEJB容器在Ȁzd体Bean实例后调用ejbLoad()Ҏ?/p>
下面的Q务就是生成一个Web服务描述Q我们通常使用工具来生成这个描q符。在q里使用J2EE提供的wscompile工具来生成。在使用wscompile工具生成web服务描述前,首先手工~写一个简单的XML描述config.xml
在这个描qCQ指定了目标的名U空间、包的名字和Web服务端点接口QHelloInterface。如下命令就可以生成一个web服务描述
c:\\ HelloBeanService\\ejb \\>wscompile -define -d . -nd . -classpath . config.xml
自动生成MyHelloBeanService.wsdl文g?/pre>7、编写一个web服务映射文gQ?br /> 在ejb\\META-INF目录下新Z个mapping.xml文gQ然后编辑这个描q符<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE java-wsdl-mapping PUBLIC
"-//IBM Corporation,Inc.//DTD J2EE JAX-RPC mapping 1.0//EN"
"http://www.ibm.com/standards/xml/webservices/j2ee/j2ee_jaxrpc_mapping_1_0.dtd">
<java-wsdl-mapping>
<package-mapping>
<package-type>HelloBeanService</package-type>
<namespaceURI>urn:HelloBean</namespaceURI>
</package-mapping>
</java-wsdl-mapping>
8、编写webservices.xml文g
另外Q还需要提供webservices.xml文gQƈ存放到Ejb-jar存档的META-INF目录中。各个J2EE产品可能提供相应的部|工h创徏q个文g?/pre>9、EJB打包
另外Qweb服务部v描述W在EJB-JAR文g中的位置是META-INF/webservices.xml.把生成的HelloBeanService.wsdl拯到ejb\\META-INF目录?br /> c:\\HelloBeanService\\ejb\\jar cvf ejb.jar com META-INF
10、Application打包
HelloBeanService\\MEAT-INF目录下创?个文Ӟapplication.xml和sun-j2ee-ri.xml
application.xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC '-//Sun Microsystems,
Inc.//DTD J2EE Application 1.3//EN'
'http://java.sun.com/dtd/application_1_3.dtd'>
<application>
<description>Application description</description>
<display-name>HelloBeanServiceApp</display-name>
<module>
<ejb>ejb.jar</ejb>
</module>
</application>
最后归?/pre>c:\\ HelloBeanService\\ejb\\>copy ejb.jar ../
c:\\ HelloBeanService\\ejb\\>cd..
c:\\ HelloBeanService\\\\>jar cvf encryptservice.ear ejb.jar META-INF
]]>
1、WSDL语言比Java更抽象、广度更大。HelloWorldWSDL中存?lt;service>标签Q它能够在具体地址提供若干<port>.<port>代表了服务接口及对具体协议的l定?br /> 2、服务描q包含了Endpoint地址。WSDL是由Java接口和对象引用构成的。换句话_Web服务不存在真正的实体Q它们不是对象,因此必须它们按照模块化对待?br /> 3、根据输入、输出定义操作。开发者需要将输入、输出消息表CZؓXML元素?br /> 4、采用的l定是SOAPl定。到目前为止Q只能采用SOAPl定。也h意,<soap:binding>标签q存在style="rpc"属性,因此可以看出styleq存在其他取|目前Q用于交换SOAP消息的另一U风格是文档风格(document-style)。文档风格意味着在SOAP消息体中不在包含对具体操作的描述?/p>
SOAP协议为Web服务和它们的客户定义了XML消息格式。SOAP消息格式非常单。它实际包含两部分内容:其一QHTTP POSTh头信息。其二,XML文档Q这是SOAP信封(Envelope)。另外,通过上述两分SOAP消息Q我们还惌达Web服务中的另一个重要概c从SOAP协议的用过E来看,它非常轻量,因ؓ它对处于交互中的客户和服务没有Q何限制。但是,从SOAP协议的大、性能角度考虑Q它q不轻量。如果不压羃SOAP消息Q则需要在|络上传递大量的SOAP数据消息。因此,采用二进制更为明智,比如CORAB的IIOP协议。对于含有大量的SOAP数据消息q行压包和解包操作将耗费大量的CPU旉。请不要忘记QWEB服务的诞生背景,它只是ؓ集成应用而来的,而不是替换现有的高性能中间件^台技术。否则,׃需要用web服务了?/p>
XML文档和^台无x,借助于标准化的XML文档QWEB服务能够帮助集成异构的分布式pȝ。在实际应用开发过E中Q它h许多优势Q比如松耦合、^台无x、遵循XML斚w的标准、能够合q不同的XML技术等。借助于XML能够实现应用和中间gq_的松耦合Q这是很重要的优ѝ?br />
比如在开发EJBlgӞ客户和服务器端同事需要用组件接口。一旦组件接口发生变动,比如需要往Ҏ{中新增参敎ͼ则EJBlg本n需要重新构建、集成、部|Ӏ当Ӟ客户也逃脱不了重新~译的命q。因此,它们之间q没有实现松耦合Q开发者不能独立的开发应用组件。否则,一旦某些组件发生变动,应用的其他部分也需要变动。我们都希望应用h良好的扩展性。对ZIIOP的请求消息而言Q所有的参与者必M用相同的cd信息Q否则不能够正确Ҏ息进行解包操作。而且Q在IIOP技术领域中Q应用必能够理解消息的所有内宏V如果基于XML和XML消息开发应用,则这些限制将不复存在?br />
J2EEq_技术对WEB服务提供了一的支持能力。无论WEB服务实现Q还是WEB服务客户Q都可以使用JAVA语言开发完成。在J2EE中,使用WEB服务同RMI、RMI-IIOPq没有多大区别。他们都具体传输层屏蔽掉,使得开发者能够专注于业务逻辑?br />
JSR921规范Q即实现企业WEB服务Q定义了WEB服务~程模型。它使用术语portlgQ描qweb服务的服务器端视图。它是服务接口的java实现。而且Q它遵@服务接口到Java的映,q提供了相应的Java实现。需要将它部|ƈq行在容器中。用EJB开发WEB服务需要创qportlg。其中,q需要提供若qXML部v描述W。当Ӟ直接ZEJB实现WEB服务是J2EEq_中实现WEB服务的最大优ѝ?/p>
JAX-RPC服务端点接口Q现在,来开发另一q程接口Q它企业Bean所提供的业务方法都列D出来Q我们称之ؓ服务Endpoint接口(Service Endpoint Interface,SEI)Q下面给Z代码?br />
JAX-RPC要求WEB服务提供SEIQEJB容器同WEB服务交互旉要用它。JAX-RPC规范要求SEI遵@如下规则Q?br />
1、接口必间接或直接l承java.rmi.Remote.
2、所有的Ҏ必须抛出java.rmi.RemoteException.
3、方法参数和q回cd必须是JAX-RPC支持的JAVAcd?br />
4、SEI中不能包含敞亮?/p>
在J2EE1.4q_中,可以对EJB技术进行了升Q得无状态会话Bean可以直接部v为Web服务端点。这P在J2ee1.4q_下,开发Web服务更加简单。这PEJB2.1中的无状态会话Bean可以?U不同的客户端:本地接口的客L、远E接口的客户端和web服务客户端。EJB的WEB服务客户端视N过WSDL文档描述?br /> 待箋......