在上一篇文章(Spring和Message Bean的整合)中,我們介紹了如何在Spring中整合Message Bean,這雖然是一個非常簡單的方法,但是Message的使用始終有一定的局限性。我們知道軟件的設計應該盡量面向對象,而MQ是面向數據的,而不是面向對象的,如果能夠在設計中介入異步方法那將比Message更加方便,更加利于理解。Lingo就是為了解決這樣的問題而誕生的。
Lingo是一個輕量級消息開發包,它基于Spring的Remoting機制并對JMS做了擴展,支持消息的同步或異步傳遞。Lingo非常高效,在線程、連接、會話和事務處理等方面都做了很好的處理,在服務器端可以和JCA整合起來,更加方便。在一定程度上,Lingo和微軟的Indigo和JSR 181類似,都允許同步和異步函數調用,同時支持對POJO的綁定,簡化對遠程服務的調用。當前Lingo只支持JMS的實現,在以后將實現更多的遠程協議,如web service等。注:CRISPY是另一款遠程調用框架,實現的目標同樣如此,目前一直支持多種協議。
講了這么多,讓我們看看如何將上一篇文章中的MDP轉換為異步方法調用。首先我們需要先下載Lingo,你可以通過 http://lingo.codehaus.org 下載。因為是異步調用,這里同樣需要MQ的支持,我們采用ActiveMQ,同時以Embed模式運行。
首先創建一個服務接口,然后實現該接口。在Lingo中,返回值為void類型,且不拋出任何異常的函數方法才可以為異步函數(還需要聲明),其他都為同步函數,這里我們要實現一個異步調用函數,就是一個簡單的方法 public void sayHello(String name)。
接下來我們要將服務的實現和MQ的Queue或Topic關聯起來,這里我們只需調用Lingo的JmsServiceExporter將服務發布出來,我們將這些信息寫在applicationContext_lingo_service.xml文件中,然后通過Spring的配置文件使其生效。我們編寫了一個普通的java類,運行該程序就可以實現異步調用的服務器端。
public class StartMQFromSpring
{
public static void main(String[] args)
{
new ClassPathXmlApplicationContext( new String[]
{
"/applicationContext_lingo_service.xml"}
);
}
}
接下來創建一個異步調用的客戶端,這里我們在applicationContext_lingo_client.xml中進行設定,然后通過一個Spring的測試用例完成客戶端的模擬操作。
public class SpringLingoTest extends AbstractDependencyInjectionSpringContextTests
{
protected String[] getConfigLocations()
{
return new String[]{"classpath*:applicationContext_lingo_client.xml"};
}
public void testAsyncronizeInvoke() throws Exception
{
HelloService service = (HelloService) applicationContext.getBean("client"); service.sayHello("jacky");
}
}
最后讓我們運行測試,首先運行StartMQFromSpring,然后運行SpringLingoTest測試用例,這樣就可以實現一個異步方法調用的例子。
總結:MDP和異步方法調用都是異步調用非常好的方法,但是異步方法調用對OO設計更加有幫助,而Message Bean則面向數據,這兩者可自行選擇。和Spring整合,更加方便地實現方法的異步調用,可以讓你的設計更加簡潔。