关键词: bpel java web服务
原文链结:http://www.theserverside.com/articles/article.tss?l=BPELJava
BPEL and Java
BPEL的作用
实现从面向过程到面向服务的转变需要一种语言以描述Web services是怎样被组织成业务流程。如果这种描述是可执行的,即允许我们定义抽象的流程,而且允许我们描述流程准确的执行规则,那将更好。而BPEL正是这样一种语言。事实上它是最先具备以下特性的语言:
1 允许我们定义抽象和可执行的流程
2 有大多数公司支持
3 软件运行在bpel流程可以执行(BPEL服务器)和设计(BPEL设计器)的平台上
在我们对BPEL做更深入的了解之前,先论述一下怎样组织web服务。这通常有两种方法:音乐演奏式和舞蹈式。音乐演奏式为一个中心进程控制相关的web services并协调在操作中被调用的web services中不同操作的执行。音乐演奏时的乐谱就是一次组织过程。被调用的web services并不知道他们被调用以组织成一个流程,也不知道他们是一个更高层业务流程的一部分(它们也不需要知道)。只有音乐演奏中的指挥者知道这些,所以音乐演奏方式是将清晰定义的操作和web services的调用顺序集中起来管理的方式。
相比而言舞蹈方式不依赖一个中心的协调器。每一个在舞蹈方式中被调用的web service清楚的知道何时执行它的操作并且知道与谁合作。舞蹈方式是专注与信息交互的合作方式。所有的参与者需要关注业务流程,操作的执行,信息的交互以及信息交互的时机。
通过对组合web services以执行业务流程的了解,音乐演奏方式比之舞蹈方式为更灵活的处理方法:
我们准确的知道谁对整个业务流程的执行负责
即使是那些不知道他们是一个业务流程一部分的web services,我们也可以组合
当错误发生时我们也可以提供可选择的替代
BPEL遵循音乐演奏的方式。舞台方式为其他标准采用,比如WSCI(Web Services Choreogaphy Interface)和WS-CDL(Web Service Choreography Description Language)。比之BPEL,舞蹈方式还没有获得业界的支持。
2002年8月,BEA、IBM、Microsoft开发出BPEL的第一个版本。从那时候起,越来越多厂商的加入使得在2003年3月在第一个版本基础上做了一些调整和改进的1.1版本的诞生。在2003年3月,BPEL被提交至OASIS组织作为标准,后来WSBPELTC组织成立。
BPEL可以在公司内部和公司之间使用。在公司内部,BPEL的作用是标准化企业应用集成和促进以前孤立系统之间的集成。在企业之间,BPEL使得业务伙伴之间的集成更容易更高效。以BPEL描述的业务流程的定义在不影响现有系统的情况下完成升级。在已经是函数环境或将要通过web services方式提供服务的环境当中BPEL是重要的技术。随着web service技术得到越来越多的使用,BPEL的重要性将日渐增强。
BPEL语言
现在让我们看一下BPEL语言。BPEL作为一种语言具体设计用来定义业务流程。BPEL支持两种不同类型的业务流程:
可执行流程允许我们指定严格的业务流程的细节,他们由音乐演奏引擎执行。在大多数情况下,BPEL被用作定义可执行的流程
抽象的业务协议允许我们指定仅仅在各参与者之间公共的信息交换。他们不包含处理流程的内部细节并且不是可执行的。
BPEL建立在XML和web services之上,它是一种基于XML的语言,支持包括SOAP,WSDL,UDDI,WS-Reliable消息,WS-Addressing,WS-Coordination和WS-Transaction的web services技术栈。BPEL汲取了两种早先的工作流语言:WSFL(Web Services Flow Language)和XLANG。WSFL由IBM设计,基于有向的内容。XLANG由微软设,是一种程序块结构语言。BPEL融合了这两种方法为业务流程的描述提供了丰富的语法。
一个BPEL流程严格指定了参与的web services被调用的顺序。这可以顺序或并行地完成。使用BPEL我们可以表示有条件的行为,例如一个web service的执行可以依赖前一个调用的结果。我们也可以构建循环,申明变量,拷贝和赋值变量,定义错误处理程序等。通过组合这些结构,我们可以以一个算法方式定义复杂的业务流程。
因此BPEL可以与像java这样的一般编程语言相比,不过没有java那样强大。但另一方面,它更简单并适合业务流程的定义。因此BPEL不是对java这样的高级语言的替代而是一个补充。让我们了解一下一个典型的BPEL流程。首先,这个BPEL业务流程收到一个请求。为了处理这个请求,流程开始调用相关的web services并将最后的结果返回给最初的请求发送者。因为BPEL流程需要与其他的web services通信,所以它非常依赖被合成web service所调用的web services的WSDL描述。
一个BPEL流程由很多个步骤组成,每一步骤被称为一个活动。BPEL支持基本的和结构化的活动。基本的活动即为基础的结构,用作公共的任务,比如:
使用调用其他的web services
通过发送一个消息等待客户端调用业务流程使用(收到一个请求)
使用对同步的操作产生响应
使用处理数据变量
使用指示错误和异常
使用等待一段时间
使用结束整个流程等等
这样我们可以组合这些和其他基本的活动定义准确反映业务流程步骤的复杂算法。为了组合基本的活动BPEL支持一些结构化的活动。其中最重要的有:
允许我们定义一系列按顺序调用的活动
用来定义一系列并行调用的活动
用来构建分支结构
用来定义循环
在许多的替代路径中选择一个的操作使用
每一个BPEL流程也可以使用申明变量,使用定义合作链接。我们将在文章的下面部分对合作链接作更多的探讨。
一个BPEL流程可能是同步也可能是异步的。一个同步的BPEL流程锁定客户端(使用这个流程的)直到这个流程完成并返回一个结果给客户端。一个异步的流程不锁定客户端,而是使用一个回调来返回结果(如果结果存在的话)。通常我们使用异步的流程实现长时间的流程,使用同步实现在一个相对短的时间里返回结果的流程。如果一个BPEL流程使用异步的web services,流程本身同时也是异步的(虽然这不是必须的)。
对于客户端来说,一个BPEL流程看起来就和其他的web service差不多。当我们定义一个流程,实际上我们是在定义一个由已存在服务组合而成的新的web service。为了调用由BPEL描述的业务流程,我们需要调用合成出来的复合web service。下图为一个BPEL流程的示意图:
合作链接
上面我们提到BPEL也申明合作链接,现在让我们解释一下什么是合作链接。我们已经提到BPEL和外部的web services的交互有两种方式:
BPEL流程调用其他web services上的操作
BPEL流程接收客户端的调用。在所有客户端中有一个是发起最初调用的BPEL流程的使用者。其他客户端是web services。举例来说,是那些已经为BPEL流程所调用,但是需要回调以返回结果。
BPEL把这些所有和它交互部分的链接称之为合作链接(partner links)。合作者链接可以是被BPEL流程调用的web services,也可以是调用BPEL流程的客户端。每一个BPEL流程至少有一个客户端合作链接,因为必然有一个调用BPEL流程的客户端。
通常一个BPEL流程也至少有一个调用的合作链接,因为它将调用至少一个web service(通常不止一个)。不管怎么样,被调用的合作链接可能成为客户端链接——这通常是在异步服务的情况下,流程调用一个操作的地方。然后这个服务(合作者)调用流程上的回调操作来返回被请求的数据。
BPEL像合作链接一样对待客户端有两个原因。最显而易见的是支持异步交互,第二个原因是基于BPEL流程可以提供服务的事实。这些通过端口类型提供的服务可以为多于一个的客户端使用。流程可能希望区分不同客户端并仅仅提供给他们经授权的功能。举例来说,一个保险流程可能提供给汽车保险客户与房产保险客户不同的一系列操作。
综上述,我们可以看到合作链接描述了指向合作者的链接,这样的合作者可能是:
流程调用的服务
调用流程的服务
两者兼而有之的服务——它们既被流程调用也调用流程
BPEL的例子
为了了解BPEL流程究竟是什么样子,下面我们给出一个选择最好保险服务的非常简单的BPEL流程。首先,我们申明指向一个BPEL流程客户端(称作client)和两个保险web服务(称作insuranceA 和 insuranceB)的合作链接。
<?xml version="1.0" encoding="utf-8"?>
<process name="insuranceSelectionProcess" targetNamespace="http://packtpub.com/bpel/example/" xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:ins="http://packtpub.com/bpel/insurance/" xmlns:com="http://packtpub.com/bpel/company/" >
<partnerLinks>
<partnerLink name="client"
partnerLinkType="com:selectionLT"
myRole="insuranceSelectionService"/>
<partnerLink name="insuranceA" partnerLinkType="ins:insuranceLT"
myRole="insuranceRequester"
partnerRole="insuranceService"/>
<partnerLink name="insuranceB" partnerLinkType="ins:insuranceLT"
myRole="insuranceRequester" partnerRole="insuranceService"/>
</partnerLinks>
...
然后,我们为保险请求申明变量(InsuranceRequest),保险A和B响应(InsuranceAResposne, InsuranceBResposne),和最终的选择(InsuranceSelectionResponse)
...
<variables>
<!-- input for BPEL process -->
<variable name="InsuranceRequest"
messageType="ins:InsuranceRequestMessage"/>
<!-- output from insurance A -->
<variable name="InsuranceAResposne" messageType="ins:InsuranceResponseMessage"/>
<!-- output from insurance B -->
<variable name="InsuranceBResposne" messageType="ins:InsuranceResponseMessage"/>
<!-- output from BPEL process -->
<variable name="InsuranceSelectionResponse" messageType="ins:InsuranceResponseMessage"/>
</variables>
...
最后,我们具体化流程步骤。首先我们从客户端等待初始的请求信息()。然后我们使用并行调用()两个保险web服务。保险服务返回保额,然后我们选择低的保额(/ )并使用将结果返回给客户(BPEL流程的调用者)
...
<sequence>
<!-- Receive the initial request from client -->
<receive partnerLink="client"
portType="com:InsuranceSelectionPT" operation="SelectInsurance" variable="InsuranceRequest"
createInstance="yes" />
<!-- Make concurrent invocations to Insurance A and B -->
<flow>
<!-- Invoke Insurance A web service -->
<invoke partnerLink="insuranceA" portType="ins:ComputeInsurancePremiumPT" operation="ComputeInsurancePremium" inputVariable="InsuranceRequest"
outputVariable="InsuranceAResposne" />
<!-- Invoke Insurance B web service -->
<invoke partnerLink="insuranceB"
portType="ins:ComputeInsurancePremiumPT"
operation="ComputeInsurancePremium"
inputVariable="InsuranceRequest"
outputVariable="InsuranceBResposne" />
</flow>
<!-- Select the best offer and construct the response -->
<switch>
<case condition="bpws:getVariableData('InsuranceAResposne',
'confirmationData','/confirmationData/Amount')
<= bpws:getVariableData('InsuranceBResposne',
'confirmationData','/confirmationData/Amount')">
<!-- Select Insurance A -->
<assign>
<copy>
<from variable="InsuranceAResposne" />
<to variable="InsuranceSelectionResponse" />
</copy>
</assign>
</case>
<otherwise>
<!-- Select Insurance B -->
<assign>
<copy>
<from variable="InsuranceBResposne" />
<to variable="InsuranceSelectionResponse" />
</copy>
</assign>
</otherwise>
</switch>
<!-- Send a response to the client -->
<reply partnerLink="client"
portType="com:InsuranceSelectionPT"
operation="SelectInsurance"
variable="InsuranceSelectionResponse"/>
</sequence>
</process>
因为每一个BPEL流程都是一个web service,每一个BPEL流程也需要一个WSDL文档。我们将不再对开发BPEL流程的更深入的细节作讨论。更多的资料可以参阅由Packt Publishing于2004年10月出版的《web服务的业务流程执行语言》(Business Process Execution Language for Web Services)
BPEL和Java
看到从上面BPEL流程的例子一些人也许会想这样一个组合用java也很容易实现。对于非常简单的流程来说这是正确的。但是对于更复杂的流程来说我们会看到BPEL比之Java的至少两个重要的优势。
BPEL比之Java的第一个优势是BPEL流程是可移植的,甚至可以运行在Java平台之外。BPEL流程可以在基于Java平台的音乐演奏服务器上运行也可以在任何其他的软件平台上运行(如.Net平台)。这在使用不同平台的B-B交互中显得尤为重要。
BPEL的第二个优势是它针对业务流程特性的支持。通常业务流程是长时间运行的,特别是他们在internet上实现与其他合作者交互的时候。有可能这样流程的执行需要几分钟,几小时,甚至是几天才能完成。有可能它们调用一个web service需要等待一个相对长的时间以获得回调的结果。如果我们不使用一个BPEL流程而是使用一个Java应用程序我们的大部分时间将会担心什么线程已经完成,什么仍然在运行。我们将不得不跟踪Java线程以确定那些我们能结束,又有哪些需要继续运行以获得回调结果。
BPEL也用相对简单的方式支持补偿。对在业务流程中那些已经成功完成操作的补偿,或者撤销操作是业务流程中最重要的问题之一。补偿的目的是恢复这个被撤销的业务流程中已经执行完成的活动。
补偿与大多数业务流程的特性相关,这种业务流程是长时间运行的并且使用异步的方式与松散耦合的web servcies通信。就成功完成来说业务流程是非常脆弱的,因为他们所使用的数据本身就是脆弱的。因为它们通常横跨多个合作伙伴(同时是多个企业),所以需要关注业务流程可能是完整执行也可能部分结果是未完成的,即补偿。这和在企业信息系统中的ACID事务类似。BPEL使用定义的补偿操作的能力支持补偿的概念(某种范围上讲这是特殊处理),这种特性称之为长时间事务(LRT)。
业务流程也可能需要对中心事件做出反映。这样的事件可能是消息事件或者警告事件。通过在端口类型上的调用操作消息事件由引入消息触发。警告事件是时间相关的,并且在一段持续时间之后或者一个特殊的时间触发。BPEL对业务流程中的事务管理提供了很好的支持。
这样就有并发活动。在BPEL中并发活动使用活动来模拟。在标签内聚集嵌套的活动非常直观,也对表示那些并不太复杂的并发场景非常有帮助。为了表达更复杂的场景,提供在活动之间表达同步依赖的能力。换句话说,我们可以具体指定哪个活动能够开始,什么时候开始(依赖其他的活动)并且可以定义复杂的依赖。举例来说,我们常常指定一个特定的活动或几个活动必须在其他一个或几个活动结束之后才能开始。
与web services的无状态模式相比业务流程模式需要使用一个有状态的模式。当一个客户端开始一个业务流程,一个新的实例将会创建。这个实例在业务流程的生命周期中存在。发送给业务流程的消息(使用在端口类型和通信端口上的操作)需要被转送到正确的业务流程实例。BPEL提供使用特定业务数据来保存指向特定业务流程实例的机制。这种功能称为相关性(correlation)。
我们可以继续讨论,不过很明显BPEL已设计用来满足定义业务流程的需要。很明显,BPEL作为一种编程语言或是一个平台来说都不能取代Java。事实上,Java平台是运行BPEL流程的一个选择。
BPEL服务器和开发工具
为了执行BPEL流程我们需要一个音乐演奏式的服务器。这样的服务器为可执行的BPEL业务流程提供一个运行的环境。BPEL与web services紧密相关,也和支持web service开发的现代软件平台紧密相关,特别是J2EE和.Net平台。
BPEL服务器可以使用J2EE或者.Net应用服务器的环境,这样他们可以使用应用服务器提供的服务,比如安全,事务,可伸缩性,和数据库的集成,EJB组件服务,如JMS的消息服务等等。
BPEL服务器在J2EE和.Net平台上都已存在。在J2EE平台下我们至少可以在以下中选择:
Oracle BPEL Process Manager (http://www.oracle.com/technology/products/ias/bpel/index.html)
IBM WebSphere Business Integration Server Foundation (http://www.ibm.com/software/integration/wbisf)
IBM alphaWorks BPWS4J (http://www.alphaworks.ibm.com/tech/bpws4j)
OpenStorm Service Orchestrator (http://www.openstorm.com)
Vergil VCAB Server (http://www.vergiltech.com/products_VCAB.php)
Active Endpoints ActiveWebflow Server (http://www.active-endpoints.com/products/index.html)
ActiveBPEL engine (http://www.activebpel.org/)
Fivesight Process eXecution Engine (http://www.fivesight.com/pxe.shtml)
基于.Net平台的BPEL服务器包括:
Microsoft BizTalk 2004 (http://www.microsoft.com/biztalk/)
OpenStorm Service Orchestrator (http://www.openstorm.com)
OpenStorm提供包括J2EE和.NET平台上的解决方案。除了BPEL音乐演奏式服务器之外还有一些可用的BPEL设计工具。这些工具支持对BPEL流程的图形化开发并通常和服务器集成在一起:
Oracle BPEL Designer
IBM WebSphere Studio Application Developer, Integration Edition
IBM BPWS4J Editor
Vergil VCAB Composer
Active Endpoints ActiveWebflow Designer
当Vergil VCAB Composer在.NET平台上建立时,Oracle, IBM和Active Endpoints的解决方案则是基于Java Eclipse框架。我们可以看到在Java平台上更多可用的BPEL服务器和设计器。
BPEL+jAVA
我们已经看到BPEL是组合web services成为业务流程的合适语言。BPEL不是一般普适性语言(也不想成为)。因此BPEL和JAVA相互配合,Java负责web services的编程实现和web services与BPEL流程的执行平台。
如在规格说明书中提到的,BPEL是可扩展的。特别是BPEL可以扩展至web services之外是非常有前景的。这意味着我们可以使用BPEL组合不同的资源而不仅仅是web services。在J2EE平台中,可能包括EJBs,JMS,RMI,JCA和其他资源。对于这个问题通常有两种解决方法:
支持BPEL和Java代码的混合,这就是BPELJ的思想
用WSDL描述所有的资源(Java classes,EJBs,JMS等等),这是Web Services调用框架中的思想
BPELJ提供在BPEL流程定义中包含java代码(称之为JAVA 片断)的可能性。这一方面使我们能够从BPEL中直接调用Java资源(BPELJ支持Java合作者链接),另一方面,它给了BPELJ增强的能力,因为使用java 片断,我们可以执行诸如计算值,构建XML文档之类的任务,也可以不用创建web服务就执行其他代码。我们也可以使用BPEL变量表达JAVA代码片段。IBM和BEA支持BPELJ,并且已经发表了BPELJ的白皮书。
将java代码整合进BPEL流程以支持调用JAVA资源是非常有用的。但是,在某些情况下这样的处理方式也会带来缺点。对一个Java资源的调用不同于对一个web service的调用。web服务调用框架(WSIF)遵循另外一种处理思路:在BPEL中使用相同的语法调用资源或服务并使用WSDL来描述,即使它是一个不通过SOAP协议通信的Java资源。WSIF也允许我们将这样的服务和实际的实现与协议相映射。
换句话说,我们可以把对抽象服务的描述与基于SOAP协议的实现绑定,与Java类绑定,与EJB绑定或者其它支持的资源,这只需要修改WSDL绑定即可。在BPEL中没有代码的更改是必须的而支持BPEL扩展也是需要的。对这种绑定的支持在由WSIF提供的支持者那里是坚定不移的。
WSIF是最初由IBM的WSTK (Web Services Toolkit)开发中alphaWorks部分发展而来的Apache技术。现在如Oracle BPEL Process Manager的一些BPEL服务器已经支持WSIF。
这两种方法,BPELJ和WSIF都适合现实世界的场景并且使得BPEL在EAI和B2B中都非常有用。
结束语
BPEL是面向过程转向面向服务的一种重要语言。因为BPEL具体设计用来定义业务流程,因此对业务流程的很多特殊性有很好的支持,如长时间事务,补偿,事件管理,相关性等等。BPEL非常适合和J2EE平台一起使用,很多BPEL服务器也是建立在J2EE之上的。结合BPEL和Java的BPELJ以及WSIF的思路使得BPEL的可用性越来越好。应该看到正在制定的JBI(Java Business Integration)规范将会在JAVA平台里给业务集成和BPEL一个更好的备有证明文件的位置。
【作者: cheney】【访问统计:644】【2006年03月27日 星期一 19:04】【注册】【打印】
Trackback
你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=4749126
分享到:
相关推荐
《PacktPub.BPEL.and.Java.Cookbook》这本书籍聚焦于Oracle BPEL(业务流程执行语言)和Java技术,旨在通过超过100个食谱帮助读者增强其面向服务的架构(SOA)复合应用。这些食谱专门针对使用中常见的问题提供解决...
BPEL和Java虽然都能实现业务逻辑,但它们的侧重点不同: - **Java**:主要用于编写业务逻辑函数,适合处理计算密集型任务,但不擅长描述服务间的交互和流程控制。 - **BPEL**:专注于业务流程和服务编排,简化了服务...
配合Java实例,可以更直观地理解BPEL的工作原理,从而实现高效的企业级流程自动化。在提供的"bpel思想详解.pdf"文件中,你可以找到更多关于BPEL的详细解释和示例,进一步深化对这一技术的理解。
BPEL(Business Process Execution Language)是一种用于描述企业服务编排和服务导向架构(SOA)中的业务流程的XML规范。它允许开发者定义复杂的业务流程,这些流程可以调用Web服务和其他可交互的业务组件。在本实例...
在Java中实现这样的逻辑相对直接,但BPEL的优势在于其标准化和跨平台性。BPEL编写的流程可以不受特定运行环境限制,在不同的BPEL引擎中得到一致的执行结果。这使得BPEL成为了SOA(面向服务架构)领域中实现服务编排...
NetBeans IDE 6提供了一套完整的工具链来支持SOA的开发,包括对XML、BPEL和Java Web服务的支持。 - XML(可扩展标记语言)用于数据交换,是SOA中服务间通信的关键技术。NetBeans IDE 6提供了强大的XML编辑器,...
这表明该项目是基于MyEclipse的插件开发,对于熟悉Java和MyEclipse的开发者来说,可以更容易地理解和修改源代码。 标签中的“绘图”提示了该工具的核心功能之一是图形用户界面的绘制。在Java中,常用的绘图库如...
本文档主要介绍了如何在 Eclipse 中搭建 BPEL 项目,包括安装和配置 Apache ODE、BPEL Designer 插件,并提供了一个小例子。 环境配置 在开始之前,需要安装 Eclipse IDE for Java EE Developers(Luna),这是一...
SOA实践:构建基于Java Web服务和BPEL的企业级应用 IBM口水书
BPEL 基于 XML 和 Web 服务构建;它使用一种基于 Web 的语言,该语言支持 web 服务技术系列,包括 SOAP、WSDL、UDDI、Web 服务可靠性消息、Web 服务寻址、Web 服务协调以及 Web 服务事务。 BPEL 代表了两种早期工作...
Oracle BPEL(Business Process Execution Language)流程开发指导是一份专为开发者准备的详细文档,主要涵盖Oracle 10g (10.1.3.1.0)版本的BPEL Process Manager的使用和开发。BPEL是一种用于描述企业服务业务流程...
BPEL(Business Process Execution Language)是一种基于XML的编程语言,用于描述和执行业务流程。在这个例子程序中,我们使用了Eclipse BPEL2.0插件来开发一个特定的流程,该流程实现了数学上的函数`fn(x,y)=[(x+y)...
Apache Tomcat是一款轻量级的Java应用服务器,主要用于部署和运行Java Servlet和JavaServer Pages(JSP)。在我们的BPEL环境中,Tomcat将作为Web服务器和应用容器,承载ActiveBPEL和Apache ODE的相关Web应用程序。 ...
- 创建两个Java类`AddService`和`SubService`分别实现加法和减法操作。 - 示例代码如下: ```java public class AddService { public double add(double a, double b) { System.out.println(a + "+" + b + "=...
此外,BPEL 2.0充分利用了XML的强大功能,如XPath和XSLT,以及诸如WS-Security、WS-Transactions等其他规格化协议,以增强安全性、事务处理能力,为复杂业务流程提供了坚实的技术基础。 ### 与BPML的关系及差异 ...
【Eclipse BPEL 知识点详解】 Eclipse BPEL(Business Process...这个过程涉及了Java开发环境的配置、Web服务的创建和部署,以及BPEL流程的设计和执行,是SOA(Service-Oriented Architecture)体系中重要的实践环节。
### BPEL整合WEBService服务的综合应用案例 在当今高度互联的世界中,服务导向架构(SOA...未来,随着云计算和微服务架构的普及,BPEL和类似的技术有望在更大范围内发挥作用,推动企业IT向更加智能化和服务化方向发展。
《SOA实践—构建基于JavaWeb服务和BPEL的企业级应用》共分8章,第1章对SOA基本概念和原则进行了讲解,第2章介绍《SOA实践—构建基于JavaWeb服务和BPEL的企业级应用》核心案例SOAgent,第3章和第4章讲述面向服务的...