1. 程式人生 > >Spring 4 2框架中註釋驅動的事件監聽器詳解

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專案的樣板程式碼,使得程式碼更加靈活,尤其是在小數量事件的需求時體現更為明顯。

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述