版權聲明:任何獲得Matrix授權的網站,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明
作者:Jeff Hanson;steven_guo
原文地址:http://www.javaworld.com/javaworld/jw-01-2005/jw-0131-soa.html
中文地址:http://www.matrix.org.cn/resource/article/43/43929_SOA_Event_driven.html
關鍵詞: SOA,Event-driven
摘要
及時響應實時的變化和事件成為了企業級架構的最重要需求。這篇文章討論面向服務框架的技術和機制,這些技術使得該框架高效發送、接受那些跨越層級結構的同步和異步事件,而不需要知道產生這些事件的系統方面的細節
Internet事務,B2B系統,P2P程序,和實時工作流,這些系統有著非常高的動態性,復雜的系統處理,用傳統的面向過程的處理方法不能有效地實現。
一個面向服務的框架代表了一個動態的運行時環境,在那里服務提供者和服務消費者松散耦合、更靈活的組件交互。建立一個具備所有這些優勢的交互模型,成為軟件開發中最優先考慮的。一個事件驅動的交互模型,比通常的請求/響應機制對實時變化和激勵有著更好的應答效率。
面向服務的架構和事件驅動的架構天生就有著對分布式系統的適應性,這些架構都有著模塊性、松散耦合,和適應性等特性。
在這篇文章里,討論使用Mule實現一個高效的事件驅動和面向服務的平臺,一個輕量級的事件-消息架構,企業信息總線(ESB)模式。組件和程序可以使用Mule通過公共的JMS或其他的消息處理技術去實現通信。
面向服務架構概述
“面向服務”這個術語已經演變成一個架構,在那里服務作為一個軟件組件嵌入在企業業務邏輯和特新的核心中,特性如下:
·????????松散耦合:服務部與其它組件有著根深蒂固的關系
·????????協議獨立:多種協議透明訪問
·????????位置不可知:一個服務執行一組業務邏輯,針對這次調用返回一個結果
·????????粗粒度:不論在什么位置均可訪問該服務。
·????????維護無用戶狀態
服務是典型地專注于解決業務領域的問題。
通常,服務使用端根據配置數據,注冊項和軟件工廠去決定給服務的位置,協議和公共接口。
應用程序通常被表述成他們有什么功能,而不強調這個應用程序是什么東西,包含什么。基于這個院應,更多直接描述一個應用程序通過使用動詞(服務)而不是用名詞(應用主體)。因為,一個名詞(應用主體)是定義了了一個事務,而不是動作,當強制把一個組件有什么功能作為一個組件是什么來定義,那就會出現誤解。在SOA領域,一個應用程序能很自然的被描述,因為每個應用程序的業務邏輯操作能被描述成為一個服務的執行選擇。因此,SOA解決了這種誤解,它允許應用程序和組件去訪問一個服務所能實現的功能,例如,他們執行什么動作。依次,應用程序開發者能更容易匹配他們的需要與適當的服務,因為服務接口的描述更完整地說清了他們要解決的問題。
事件驅動架構概述
一個事件驅動框架(EDA)定義了一個設計和實現一個應用系統得方法學,在這個系統里事件可傳輸于松散耦合的軟件組件和服務之間。一個事件驅動系統典型地由事件消費者和事件產生者組成。事件消費者向事件管理器訂閱事件,事件產生者向事件管理器發布事件。當事件管理器從事件產生者那接收到一個事件時,事件管理把這個事件轉送給相應的事件消費者。如果這個事件消費者是不可用的,事件管理這將保留這個事件,一段間隔之后再次轉送該事件消費者。這種事件傳送方法在基于消息的系統里就是:儲存(store)和轉送(forward)。
構建一個包含事件驅動構架的應用程序和系統,這樣就使得這些應用程序和系統響應更靈敏,因為事件驅動的系統更適合應用在不可預知的和異步的環境里。
事件驅動設計和開發的優勢:
事件驅動設計和開發所提供的優勢如下:
·????????可以更容易開發和維護大規模分布式應用程序和不可預知的服務或異步服務
·????????可以很容易,低成本地集成、再集成、再配置新的和已存在的英勇程序和服務
·????????促進遠程組件和服務的再使用,擁有一個更靈敏、沒有Bug的開發環境
·????????短期利益:更容易定制。因為設計對動態處理又更好的響應。
·????????長期利益:系統和組織的狀態變得更精準,對實時變化的響應接近于同步。
EDA 和 SOA 整合
不象請求/響應系統,要求請求者必須明確發送請求信息,而一個事件驅動 架構提供一個機制去動態響應事件。在一個EDA系統里,事件產生者發布事件,事件消費者接受事件。
業務系統可以從SOA和EDA中受益匪淺,因為當事件發生時EDA能觸發事件消費者,SOA服務可以快速地從相同的消費者中訪問、查詢。
系統要有最高的響應性,當事件觸發時這個系統必須能快速決定必須的動作。到事件結束,事件應該被發布和消費,而且事件要穿越SOA所有的邊界,包括整個體系結構和物理層。
圖1演示了事件被激發和穿越體系結構的所有層

圖1:事件穿越體系結構的層級
在圖1的環境中,一個事件能被定義為任何系統的,平臺的,組件的,業務的或英勇進程的變化。事件可能是高層的業務事件或底層的系統事件。因為事件能被傳送和接收,訂閱事件的英勇程序和服務能對這些變化做出響應。
事件分類和因果關系
理解一個事件的秘訣是知道這個事件發生的原因,這個就是通常說的因果關系。事件的因果關系典型地分為兩類:
·????????平行關系:時間源和觸發在體系結構的同一層。
·????????垂直關系:時間源和觸發在體系結構的不同層。
垂直關系意味著一個事件的分類方法,這些事件保留了一些不變的東西而穿越一個系統不同的層,事件分類如下:
·????????生命周期事件:一個實體生命周期的變化,例如一個進程的停止或啟動
·????????執行事件:運行時事件,例如服務或組件的調用
·????????管理事件:當一個狀態超過了預先的定義或一定范圍時
平行關系意味著一個事件的分類方法,這些事件保留了一些不變的東西而穿越一個系統不同的層,事件分類如下:
·????????系統層事件:系統級動作,例如創建一個文件或關閉一個端口
·????????平臺層事件:平臺級動作,例如修改一個數據源或增加一個新的服務
·????????組件層事件:組件級動作,例如視圖對象的轉換或狀態機變化
·????????業務層事件:業務級動作,例如創建用戶或刪除帳號
·????????應用層事件:應用級動作,例如增加保險金或報價提交
許多ESB框架和平臺意識到在SOA中包含基于事件驅動的通信有很多優勢。在Java開發領域,Mule就是這些最有前景的平臺之一。
介紹Mule
Mule是一個開源消息ESB框架,一個消息代理,一個分級事件驅動的框架(SEDA)。SEDA定義了一個依照分級隊列、高度并行的企業級平臺。Mule使用SED的概念增加事件處理的性能。
Mule支持同步、異步和請求響應事件,事件處理和傳輸實用不同的技術例如JMS,HTTP,電子郵件和基于XML的RPC。Mule能很容易地嵌入到任何應用框架中,明確支持Spring框架。Mule也支持動態的,預定義的,基于內容的和基于規則的消息路由。Mule使得預定義的和計劃性的事務更容易,包括XA事務支持。Mule提供一個有代表性的狀態調用(REST)API提供給與Web的事件訪問。
Mule ESB模式驅動系統中所有服務,這個系統有著一個分離的消息通訊中樞。服務注冊在總線上,但不知道其他任何被注冊的消息;因此,每個服務只關心處理它收到的事件。Mule也把容器,傳輸,轉換細節從服務中分離出來,允許任何對象作為服務注冊到總線的。
我使用Mule框架去演示這篇文章所討論的概念和思想
Mule框架
Mule框架主要包含下列內容:
通用消息對象(UMO)API
UMO API第一了所有被Mule 管理的服務和對象交互
UMO組件
在Mule系統中,UMO組件可以使任何在系統中接收、處理和發送事件消息的組件
Mule服務器
Mule服務器組件是一個在Mule應用環境中自動加載的服務器應用程序
描述器
描述器組件描述一個Mule UMO屬性。新的Mule MUO對象能被它們所關聯的描述器初始化。一個描述器包含:
·????????UMO組件名
·????????UMO組件版本
·????????UMO組件實現類
·????????異常策略
·????????入站和出站提供者
·????????入站和出站路由器
·????????攔截器
·????????接收和發送切入點
·????????入站和出站轉換器
·????????各種各樣的特性
連接器
連接器是一些組件,它們可以連接到外部系統或其他協議、管理那些系統或協議的狀態。一個連接器負責發送消息到外部消息接收器、管理消息接收器的注冊和注銷。
提供者
提供者是一些組件,管理把事件數據發送到外部系統、從外部系統接受事件數據和轉換事件數據等事項。在Mule框架里,他們能連接到外部系統或其他組件。一個提供者就像一個從外部系統進入Mule或從Mule內部訪問外部系統的橋接器。實際上,提供者有一組對象組成,可以與下層系統連接并與之通信。提供者的組成部件是:
·????????連接器:負責連接到下層系統
·????????消息接收器:從系統接收事件
·????????連接調度者:傳送系統到系統
·????????轉換器:轉換從系統接收到的或要發送到系統的數據
·????????終端:所建立連接的通道地址
·????????事務配制:定義連接的事務屬性
終端調解者
當UMO組件接收到一個事件時,終端調解者決定去調用它的什么方法
轉換器
轉換器組件負責雙向轉換消息或事件的有效載荷。當一個事件到達接收的對象之前,轉換器可以鏈接到一起去執行一系列的裝換操作。
消息適配器
消息適配器提供一中公共的方式去讀外部系統的異構數據。
消息接收器
消息接收器是一些列終端監聽線程,負責從外部系統接收數據。
消息調度者
消息調度者發送(同步)或派遣(異步)時間到下層系統。
消息路由器
消息路由器是一系列組件,可以使被配制的UMO組件依據消息或其他配制圖路有一個消息到不同的提供者。
代理
代理是一些幫定到外部服務的組建,例如JME服務器。
Mule模型
一個Mule模型封裝和管理一個Mule服務器實例的運行時行為。一個模型包含:
·????????描述器
·????????UMO組件
·????????一個終端調解者
·????????一個生命周期適配器工廠
·????????一個組件調解者
·????????一個池化工廠
·????????一個異常策略
Mule管理器
Mule管理器維護和提供以下服務 :
·????????代理
·????????提供者
·????????連接器
·????????終端
·????????轉換器
·????????攔截器堆棧
·????????一個Mule模型
·????????一個Mule服務器
·????????事務管理器
·????????應用程序屬性
·????????Mule配制
圖2演示了Mule框架上層消息流視圖

圖2:Mule上層架構
Mule事件對象
Mule事件對象對象包含事件數據和被組件所感知和操控的屬性。屬性是任意的,在事件創建之后任何時間可被設置。
org.mule.umo.UMOEvent類代表了一個在Mule環境中出現的時間。所有在組件之間發送或接收的數據都是org.mule.umo.UMOEvent的一個實體。可以訪問一個原始的或被轉換的Mule事件對象中的數據能。一個Mule事件對象使用一個與提供者管理的提供者轉換數據,提供者收到數據后把事件中的有效載荷轉換成當前組件所識別的格式。
一個Mule事件對象的有效有效載荷能通過org.mule.umo.UMOMessage接口訪問,一個org.mule.umo.UMOMessage實例由有效載荷和它的屬性組成。這個接口是不同技術實現的消息對象的一個抽象。
org.mule.extras.client.MuleClient類定義了一個簡單的借口,允許Mule客戶端從Mule服務器接收和發送事件數據。在大多數Mule應用程序里,時間是被一些外部的并發行為所觸發,例如一個主題上接收到消息或在目錄里一個文件被刪除。
下面演示了如何去發送一個同步事件到另外的Mule組件:
String componentName = "MyReceiver"; // The name of the receiving component.
String transformers = null; // A comma-separated list of transformers
????????????????????????????// to apply to the result message.
String payload = "A test event"; // The payload of the event.
java.util.Map messageProperties = null; // Any properties to be associated
????????????????????????????????????????// with the payload.
MuleClient client = new MuleClient();
UMOMessage message = client.sendDirect(componentName,
?????????????????????????????????????? transformers,
?????????????????????????????????????? payload,
?????????????????????????????????????? messageProperties);
System.out.println("Event result: " + message.getPayloadAsString());
MuleClient類需要一個服務器URL區定義它所連接的遠程Mule服務器的終端。URL定義了傳輸協議、接收消息的地址,提供者在派遣一個事件時可以隨時使用這些信息。終端例示如下:
·????????vm://com.jeffhanson.receivers.Default: 使用虛擬機的提供者派遣到一個com.jeffhanson.receivers.Default
·????????jms://jmsProvider/accounts.topic:使用全局注冊的jmsProvider派遣一個JMS消息到ccounts.topic.
·????????jms://accounts.topic: 使用第一個(默認)的JMS提供者派遣JMS消息
Mule事件處理
Mule可以在三種不同的方式發送和節后艘事件:
1.異步方式:一個組件可通過不同的線程同時處理多個事件的發送和接收
2.同步方式:在一個組件重新工作之前,一個單一的事件必須被處理完。換言之,一個創建了事件的組建發送事件時將被阻斷,直到發送任務完成,因此,一次只允許處理一個事件
3.請求-應答方式:一個組建專門請求一個事件,然后等待一個特定的時間去接收回應。
org.mule.impl.MuleComponent實現類提供了一個具體的組建類,它包括又有創建,發送和接收事件的功能。
執行同步動作的對象應該實現org.mule.umo.lifecycle.Callable接口,這個定義了一個簡單的方法Object onCall(UMOEventContext eventContext)。Callable接口提供支持事件調用的UMO對象。雖然不是強制的,但這個接口提供了一個生命周期控制的方法,當實現這個接口的組建接收到一個消息時執行這個方法。下面展示了這個接口的簡單實現。
import org.mule.umo.lifecycle.Callable;
public class EchoComponent
?? implements Callable
{
????public Object onCall(UMOEventContext context) throws Exception
????{
????????String msg = context.getMessageAsString();
????????// Print message to System.out
????????System.out.println("Received synchronous message: " + msg);
????????// Echo transformed message back to sender
????????return context.getTransformedMessage();
????}
}
從onCall()方法可返回任何對象。當組件的UMOLifecycleAdapter接收這個對象時,它首先看看這個對象是否是一個UMOMessage;如果這個對象既不是UMOMessage也不是Null,那么以這個對象作為有效載荷去創建一個新的消息。這個新事件經由所配制的出站路有器發布,如果UMO對象已經配制了一個出站路由器,那么在UMOEventContext實例中不能調用setStopFurtherProcessing(true)方法。
Mule使用的一個簡單的事件框架
讓我們把這幾段Mule的代碼放到一起去構建一個簡單的事件框架。這個框架包含一個負責注冊和注銷事件的管理器,可以接收事件,和負責路有同步和異步消息到他們相應的服務。
Mule的虛擬機協議要求有一個放置事件管理器工作目錄META-INF/services/org/mule/providers/vm路徑下的可配制文件,配制文件為協議定義了大量的組件,例如連接器和調度工廠。配制文件的內容如下:
connector=org.mule.providers.vm.VMConnector
dispatcher.factory=org.mule.providers.vm.VMMessageDispatcherFactory
message.receiver=org.mule.providers.vm.VMMessageReceiver
message.adapter=org.mule.providers.vm.VMMessageAdapter
endpoint.builder=org.mule.impl.endpoint.ResourceNameEndpointBuilder
一個簡單的借口定義了事件管理器的公有結構:
package com.jeffhanson.mule;
import org.mule.umo.FutureMessageResult;
public interface EventManager
{
?? /**
????* Sends an event message synchronously to a given service.
????*
????* @param serviceName????The name of the service to which the event
????*?????????????????????? message is to be sent.
????* @param payload????????The content of the event message.
????* @return Object????????The result, if any.
????* @throws EventException on error
????*/
?? public Object sendSynchronousEvent(String serviceName,
??????????????????????????????????????Object payload)
??????throws EventException;
?? /**
????* Sends an event message asynchronously to a given service.
????*
????* @param serviceName????The name of the service to which the event
????*?????????????????????? message is to be sent.
????* @param payload????????The content of the event message.
????* @return FutureMessageResult The result, if any.
????* @throws EventException on error
????*/
?? public FutureMessageResult sendAsynchronousEvent(String serviceName,
????????????????????????????????????????????????????Object payload)
??????throws EventException;
?? /**
????* Starts this event manager.
????*/
?? public void start();
?? /**
????* Stops this event manager.
????*/
?? public void stop();
?? /**
????* Retrieves the protocol this event manager uses.
????* @return
????*/
?? public String getProtocol();
?? /**
????* Registers a service to receive event messages.
????*
????* @param serviceName??????The name to associate with the service.
????* @param implementation?? Either a container reference to the service
????*???????????????????????? or a fully-qualified class name.
????*/
?? public void registerService(String serviceName,
?????????????????????????????? String implementation)
??????throws EventException;
?? /**
????* Unregisters a service from receiving event messages.
????*
????* @param serviceName??The name associated with the service to unregister.
????*/
?? public void unregisterService(String serviceName)
??????throws EventException;
}
事件管理器類是被封裝在一個工廠類里,因此,可以依據需要去改變它的實現而不會影響到它的客戶端。事件管理器實現如下:
package com.jeffhanson.mule;
import org.mule.umo.*;
import org.mule.extras.client.MuleClient;
import org.mule.impl.endpoint.MuleEndpoint;
import org.mule.config.QuickConfigurationBuilder;
import java.util.HashMap;
import java.util.Map;
public class EventManagerFactory
{
?? private static HashMap instances = new HashMap();
?? /**
????* Retrieves the event manager instance for a given protocol.
????*
????* @param protocol??????The protocol to use.
????* @return EventManager The event manager instance.
????*/
?? public static EventManager getInstance(String protocol)
?? {
??????EventManager instance = (EventManager)instances.get(protocol);
??????if (instance == null)
??????{
???????? instance = new EventManagerImpl(protocol);
???????? instances.put(protocol, instance);
??????}
??????return instance;
?? }
?? /**
????* A concrete implementation for a simple event manager.
????*/
?? private static class EventManagerImpl
??????implements EventManager
?? {
??????private UMOManager manager = null;
??????private QuickConfigurationBuilder builder = null;
??????private MuleClient eventClient = null;
??????private String protocol = null;
??????private MuleEndpoint receiveEndpoint = null;
??????private MuleEndpoint sendEndpoint = null;
??????private EventManagerImpl(String protocol)
??????{
???????? this.protocol = protocol;
??????}
??????/**
?????? * Starts this event manager.
?????? */
??????public void start()
??????{
???????? try
???????? {
????????????builder = new QuickConfigurationBuilder();
????????????manager = builder.createStartedManager(true,
?????????????????????????????????????????????????? protocol + "tmp/events");
????????????eventClient = new MuleClient();
????????????receiveEndpoint = new MuleEndpoint(protocol
?????????????????????????????????????????????? + "tmp/events/receive");
????????????sendEndpoint = new MuleEndpoint(protocol + "tmp/events/send");
???????? }
???????? catch (UMOException e)
???????? {
????????????System.err.println(e);
???????? }
??????}
??????/**
?????? * Stops this event manager.
?????? */
??????public void stop()
??????{
???????? try
???????? {
????????????manager.stop();
???????? }
???????? catch (UMOException e)
???????? {
????????????System.err.println(e);
???????? }
??????}
??????/**
?????? * Retrieves the protocol this event manager uses.
?????? * @return
?????? */
??????public String getProtocol()
??????{
???????? return protocol;
??????}
??????/**
?????? * Registers a service to receive event messages.
?????? *
?????? * @param serviceName??????The name to associate with the service.
?????? * @param implementation?? Either a container reference to the service
?????? *???????????????????????? or a fully-qualified class name
?????? *???????????????????????? to use as the component implementation.
?????? */
??????public void registerService(String serviceName,
??????????????????????????????????String implementation)
???????? throws EventException
??????{
???????? if (!manager.getModel().isComponentRegistered(serviceName))
???????? {
????????????try
????????????{
?????????????? builder.registerComponent(implementation,
???????????????????????????????????????? serviceName,
???????????????????????????????????????? receiveEndpoint,
???????????????????????????????????????? sendEndpoint);
????????????}
????????????catch (UMOException e)
????????????{
?????????????? throw new EventException(e.toString());
????????????}
???????? }
??????}
??????/**
?????? * Unregisters a service from receiving event messages.
?????? *
?????? * @param serviceName??The name associated with the service to unregister.
?????? */
??????public void unregisterService(String serviceName)
???????? throws EventException
??????{
???????? try
???????? {
????????????builder.unregisterComponent(serviceName);
???????? }
???????? catch (UMOException e)
???????? {
????????????throw new EventException(e.toString());
???????? }
??????}
??????/**
?????? * Sends an event message synchronously to a given service.
?????? *
?????? * @param serviceName????The name of the service to which the event
?????? *?????????????????????? message is to be sent.
?????? * @param payload????????The content of the event message
?????? * @return Object????????The result, if any.
?????? * @throws EventException on error
?????? */
??????public Object sendSynchronousEvent(String serviceName,
???????????????????????????????????????? Object payload)
???????? throws EventException
??????{
???????? try
???????? {
????????????if (!manager.getModel().isComponentRegistered(serviceName))
????????????{
?????????????? throw new EventException("Service: " + serviceName
????????????????????????????????????????+ " is not registered.");
????????????}
????????????String transformers = null;
????????????Map messageProperties = null;
????????????UMOMessage result = eventClient.sendDirect(serviceName,
?????????????????????????????????????????????????????? transformers,
?????????????????????????????????????????????????????? payload,
?????????????????????????????????????????????????????? messageProperties);
????????????if (result == null)
????????????{
?????????????? return null;
????????????}
????????????return result.getPayload();
???????? }
???????? catch (UMOException e)
???????? {
????????????throw new EventException(e.toString());
???????? }
???????? catch (Exception e)
???????? {
????????????throw new EventException(e.toString());
???????? }
??????}
??????/**
?????? * Sends an event message asynchronously.
?????? *
?????? * @param serviceName????The name of the service to which the event
?????? *?????????????????????? message is to be sent.
?????? * @param payload????????The content of the event message.
?????? * @return FutureMessageResult The result, if any
?????? * @throws EventException on error
?????? */
??????public FutureMessageResult sendAsynchronousEvent(String serviceName,
?????????????????????????????????????????????????????? Object payload)
???????? throws EventException
??????{
???????? FutureMessageResult result = null;
???????? try
???????? {
????????????if (!manager.getModel().isComponentRegistered(serviceName))
????????????{
?????????????? throw new EventException("Service: " + serviceName
????????????????????????????????????????+ " is not registered.");
????????????}
????????????String transformers = null;
????????????Map messageProperties = null;
????????????result = eventClient.sendDirectAsync(serviceName,
???????????????????????????????????????????????? transformers,
???????????????????????????????????????????????? payload,
???????????????????????????????????????????????? messageProperties);
???????? }
???????? catch (UMOException e)
???????? {
????????????throw new EventException(e.toString());
???????? }
???????? return result;
??????}
?? }
}
Mule框架依據消息有效載荷的類型來派遣消息。事件框架使用基于有效載荷的派遣機制,這種派遣機制把注冊到事件管理器中一般定義的事件方法作為事件接收器。下面的類定義了一個包含三個重載的receiveEvent()方法的服務:
package com.jeffhanson.mule;
import java.util.Date;
public class TestService
{
?? public void receiveEvent(String eventMessage)
?? {
??????System.out.println("\n\nTestService.receiveEvent(String) received "
???????????????????????? + "event message:??" + eventMessage + "\n\n");
?? }
?? public void receiveEvent(Integer eventMessage)
?? {
??????System.out.println("\n\nTestService.receiveEvent(Integer) received "
???????????????????????? +"event message:??" + eventMessage + "\n\n");
?? }
?? public void receiveEvent(Date eventMessage)
?? {
??????System.out.println("\n\nTestService.receiveEvent(Date) received "
???????????????????????? + "event message:??" + eventMessage + "\n\n");
?? }
}
事件管理器客戶端應用程序發送三個事件到測試服務中,去測試每一個receiveEvent()方法。客戶端應用程序如下:
package com.jeffhanson.mule;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.BasicConfigurator;
import java.util.Date;
public class EventClient
{
?? static Logger logger = Logger.getLogger(EventClient.class);
?? public static void main(String[] args)
?? {
??????// Set up a simple configuration that logs on the console.
??????BasicConfigurator.configure();
??????logger.setLevel(Level.ALL);
??????try
??????{
???????? EventManager eventManager =
????????????EventManagerFactory.getInstance("vm://");
???????? eventManager.start();
???????? String serviceName = TestService.class.getName();
???????? String implementation = serviceName;
???????? eventManager.registerService(serviceName, implementation);
???????? Object result =
????????????eventManager.sendSynchronousEvent(serviceName, "A test message");
???????? if (result != null)
???????? {
????????????System.out.println("Event result: " + result.toString());
???????? }
???????? result =
????????????eventManager.sendSynchronousEvent(serviceName, new Integer(23456));
???????? if (result != null)
???????? {
????????????System.out.println("Event result: " + result.toString());
???????? }
???????? result =
????????????eventManager.sendSynchronousEvent(serviceName, new Date());
???????? if (result != null)
???????? {
????????????System.out.println("Event result: " + result.toString());
???????? }
???????? eventManager.stop();
??????}
??????catch (EventException e)
??????{
???????? System.err.println(e.toString());
??????}
?? }
}
Mule平臺簡化和抽象了前面所敘述框架的事件方面的處理,使得你發送和接收穿越一個層級結構的同步和異步消息時,不需要知道下層系統的細節。工廠模式和SOA準則的應用,則使得這個框架有了一個松散耦合和可擴展的設計。
總結
當服務和進程需要穿越多層結構,使用多種協議去交互時,設計一個有效地事件驅動的軟件系統可能變得復雜了。可是,一個使用標準模式包含適當事件管理層的面向服務架構能減少,甚至消除這些問題。
Mule 平臺提供API,組件和抽象對象,這些都可以用于去建立一個強大,健壯,事件驅動的有著良好的伸縮性和可維護性的系統。
關于作者
Jeff Hanson 有著18年的軟件行業從業經驗,曾經作為高級軟件工程師工作于Windows OpenDoc項目,作為主管架構師在Novell的Route66框架工作。現在,作為eReinsure.com的首席架構師,正在構建Web服務框架和基于J2EE再保險平臺。Hanson已經寫作了大量的文章和書籍,包括:《Pro JMX: Java Management Extensions》(Apress出版社,2003年11月; ISBN: 1590591011)和《Web Services Business Strategies and Architectures》(Wrox 出版社,2002年8月; ISBN: 1904284132)
資源
·javaworld.com:javaworld.com
·Matrix-Java開發者社區:http://www.matrix.org.cn/
·Mule主頁: http://wiki.muleumo.org/display/MULEPROJ/Home
·Mule FAQ: http://wiki.muleumo.org/display/MULE/Mule+FAQ