Spring 4 2框架中註釋驅動的事件監聽器詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
Spring 4.2框架中註釋驅動的事件監聽器詳解
作者:chszs,版權所有,未經同意,不得轉載。博主主頁: http://blog.csdn.net/chszs
事件互動已經成為很多應用程式不可或缺的一部分,Spring框架提供了一個完整的基礎設施來處理瞬時事件。下面我們來看看Spring 4.2框架中基於註釋驅動的事件監聽器。
1、早期的方式
在早期,元件要從Spring事件獲知自定義域事件中獲取通知,那麼元件必須實現ApplicationListener介面並覆寫onApplicationEvent方法。
@Componentclass OldWayBlogModifiedEventListener implements ApplicationListener<OldWayBlogModifiedEvent> { (...) @Override public void onApplicationEvent(OldWayBlogModifiedEvent event) { externalNotificationSender.oldWayBlogModified(event); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
上面的程式碼工作正常,但是它會針對每一個事件都建立一個新類,從而造成程式碼瓶頸。
另外,我們的事件類繼承了ApplicationEvent類——Spring應用中的事件基類。
class OldWayBlogModifiedEvent extends ApplicationEvent { public OldWayBlogModifiedEvent(Blog blog) { super(blog); } public Blog getBlog() { return (Blog)getSource(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
請注意,在事件中使用Domain域物件有明顯的缺點,在一些場景下不可用。這裡只是做程式碼示例。
順便說一句,ExternalNotificationSender物件負責傳送外部通知給已註冊的使用者(例如通過電子郵件、簡訊等方式)。
2、註釋驅動的事件監聽器
Spring 4.2框架值得注意的一點,用註釋@EventListener註解任意的Spring元件。
@EventListenerpublic void blogModified(BlogModifiedEvent blogModifiedEvent) { externalNotificationSender.blogModified(blogModifiedEvent);}
- 1
- 2
- 3
- 4
Spring會為事件建立一個ApplicationListener例項,並從方法引數中獲取事件的型別。一個類中被事件註釋的方法數量沒有限制,所有相關的事件控制代碼都會分組到一個類中。
3、有條件的事件處理
為了使註釋@EventListener的功能更強大,Spring 4.2支援用SpEL表示式表達事件型別的方式。假設以下是事件類:
public class BlogModifiedEvent { private final Blog blog; private final boolean importantChange; public BlogModifiedEvent(Blog blog) { this(blog, false); } public BlogModifiedEvent(Blog blog, boolean importantChange) { this.blog = blog; this.importantChange = importantChange; } public Blog getBlog() { return blog; } public boolean isImportantChange() { return importantChange; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
要注意,在實際應用中可能不會有本文這樣的層次結構的事件。
還要注意,用Groovy編寫會更加簡單。
使用條件引數來闡述事件,重要的變化是:
@EventListener(condition = "#blogModifiedEvent.importantChange")public void blogModifiedSpEL(BlogModifiedEvent blogModifiedEvent) { externalNotificationSender.blogModifiedSpEL(blogModifiedEvent);}
- 1
- 2
- 3
- 4
4、寬鬆事件型別的層次結構
Spring 4.2之前的版本,ApplicationEventPublisher只有在ApplicationEvent事件後釋出其繼承物件的能力。而在Spring 4.2版開始,此介面已經擴充套件到支援任意物件型別。在這種情況下,物件被封裝到PayloadApplicationEvent和通過傳送。
//base class with Blog field - no need to extend `ApplicationEvent`class BaseBlogEvent {}class BlogModifiedEvent extends BaseBlogEvent {}//somewhere in the codeApplicationEventPublisher publisher = (...); //injectedpublisher.publishEvent(new BlogModifiedEvent(blog)); //just plain instance of the event
- 1
- 2
- 3
- 4
- 5
- 6
這一變化使得釋出事件更容易。然而另一方面它可以導致事件跟蹤變得更加困難,特別是在大型應用程式中。
5、響應釋出事件
註釋@EventListener還有一點需注意,在非空返回型別時,Spring會自動釋出返回的事件。
@EventListenerpublic BlogModifiedResponseEvent blogModifiedWithResponse(BlogModifiedEvent blogModifiedEvent) { externalNotificationSender.blogModifiedWithResponse(blogModifiedEvent); return new BlogModifiedResponseEvent( blogModifiedEvent.getBlog(), BlogModifiedResponseEvent.Status.OK);}
- 1
- 2
- 3
- 4
- 5
- 6
6、非同步事件處理
註釋@EventListener還可以與註釋@Async進行組合使用,以提供非同步事件處理的機制。下面的程式碼中,指定的事件監聽器既不會阻塞主要的程式碼執行,又不會被其它的監聽器處理。
@Async //Remember to enable asynchronous method execution //in your application with @[email protected] void blogAddedAsync(BlogAddedEvent blogAddedEvent) { externalNotificationSender.blogAdded(blogAddedEvent);}
- 1
- 2
- 3
- 4
- 5
- 6
為了使工作能夠得到非同步執行,通常還需在Spring專案的上下文中使用註釋@EnableAsync。
7、總結
註釋驅動的事件監聽器是Spring框架4.2版中引入的新特性,它減少了Spring專案的樣板程式碼,使得程式碼更加靈活,尤其是在小數量事件的需求時體現更為明顯。