javascript
java观察者模式在spring中的应用_Spring源码之spring中的观察者模式和监听器的使用...
聲明:本文根據魯班學院子路老師spring中觀察者模式課程整理得來
觀察者模式特點:
被觀察者持有監聽的觀察者的引用。
被觀察者支持增加和刪除的觀察者。
被觀察者狀態改變通知觀察者。
JDK中觀察者implements Observer接口,重寫update()方法
當觀察者發生變化,收到通知進行具體的處理
可以隨時取消
松耦合:
觀察者增加或者刪除無需修改被觀察者的代碼,只需調用被觀察者對應的增加或則刪除的方法即可
被觀察者只負責通知觀察者,但無需了解觀察者如何處理通知
觀察者只需等待被觀察者通知,無需觀察被觀察者細節
通知不會錯過:
由于被動接受,正常情況下不會錯過主體的改變通知,而主動獲取的話,由于時機選擇問題,可能導致錯過某些狀態
Java實現
Java中有觀察者模式使用的API
Java.util.Observable 這是一個類
java.util.Observer 這是一個接口
開關的重要性
可以篩選通知
可以撤銷通知
可以控制通知
Spring中的觀察者模式
在Spring中定義和應用程序上下文相關的事件時需要繼承ApplicationEvent類
public abstract class ApplicationEvent extendsEventObject {/**use serialVersionUID from Spring 1.2 for interoperability.*/
private static final long serialVersionUID = 7099057708183571937L;/**System time when the event happened.*/
private final longtimestamp;/*** Create a new {@codeApplicationEvent}.
*@paramsource the object on which the event initially occurred or with
* which the event is associated (never {@codenull})*/
publicApplicationEvent(Object source) {super(source);this.timestamp =System.currentTimeMillis();
}/*** Return the system time in milliseconds when the event occurred.*/
public final longgetTimestamp() {return this.timestamp;
}
}
在ApplicationEvent的父類EventObject類(這個是java源碼中的類)中有一個得到事件源的方法getSource()
Spring中的Events
事件通過**org.springframework.context.ApplicationEvent**實例來表示。這個抽象類繼承擴展了**java.util.EventObject**,可以使用**EventObject中的getSource**方法,我們可以很容易地獲得所發生的給定事件的對象。這里,事件存在兩種類型。
1. **與應用程序上下文相關聯**
所有這種類型的事件都繼承自**org.springframework.context.event.ApplicationContextEvent**類。
它們應用于由**org.springframework.context.ApplicationContext**引發的事件(其構造函數傳入的是`ApplicationContext`類型的參數)。
這樣,我們就可以直接通過應用程序上下文的生命周期來得到所發生的事件:`ContextStartedEvent`在上下文啟動時被啟動,當它停止時啟動`ContextStoppedEvent`,當上下文被刷新時產生`ContextRefreshedEvent`,最后在上下文關閉時產生`ContextClosedEvent`。
以ContextStartedEvent這個類為例,實現SpringEvent的擴展功能,這個事件在context.start()的時候來進行監聽處理。
public class ContextStartedEvent extendsApplicationContextEvent {/*** Create a new ContextStartedEvent.
*@paramsource the {@codeApplicationContext} that has been started
* (must not be {@codenull})*/
publicContextStartedEvent(ApplicationContext source) {super(source);
}
}
1.首先創建一個listener類
/*** spring通過實現ApplicationListener這個接口,同時傳入一個泛型(ContextStartedEvent)就可以
* 監聽到這個泛型對應的事件*/@Componentpublic class SpringListenerStart implements ApplicationListener{
@Overridepublic voidonApplicationEvent(ContextStartedEvent event) {
System.out.println("----- spring application start listener------");
}
}
2.創建測試類
public classTest {public static voidmain(String[] args) {
AnnotationConfigApplicationContext context= new AnnotationConfigApplicationContext(WkApplication.class);
context.start();//在調用context的start()方法時,會觸發spring的監聽器,調用ContextStartedEvent對應的事件方法
}
}
3.運行結果
Spring監聽器的應用(模擬一個發郵件的監聽器):
1.創建一個SpringMailEvent類,使它繼承ApplicationEvent類(這個是Spring的事件類,自己的事件都要繼承它)
public class SpringMailEvent extends ApplicationEvent implementsSerializable {//需要序列化,要不會報錯。我也不知道為什么
private static final long serialVersionUID=762508508425139227l;privateString content;/*** Create a new {@codeApplicationEvent}.
*
*@paramsource the object on which the event initially occurred or with
* which the event is associated (never {@codenull})*/
publicSpringMailEvent(Object source) {super(source);
}publicString getContent() {returncontent;
}public voidsetContent(String content) {this.content =content;
}
}
2.創建一個SpringMailListener監聽器類,使他實現ApplicationListener接口,同時泛型中穿我們自己定義的事件
@Componentpublic class SpringMailListener implements ApplicationListener{/*** 當程序調用了一個發郵件的方法時,這個監聽器就會監聽到,
* 同時在onApplicationEvent方法中做出響應
*@paramevent the event to respond to*/@Overridepublic voidonApplicationEvent(SpringMailEvent event) {
System.out.println("mail send ");
}
}
3.創建一個類,使自定義的監聽器和事件與spring容器關聯起來
/*** 創建自己的類,使自定義的監聽器和事件與spring容器關聯起來*/@Componentpublic classMailBean {
@Autowired
ApplicationContext context;//注入Sprig應用程序上下文/*** 我們之前只是定義了SpringMailEvent類,但是這個類并沒有和Spring容器關聯起來,
* 所以我們需要借助ApplicationContext的publishEvent()方法,把這個事件發布出去*/
public voidsendMail(){
context.publishEvent(newSpringMailEvent(context));
}
}
4.測試類
public classTest {public static voidmain(String[] args) {
AnnotationConfigApplicationContext context= new AnnotationConfigApplicationContext(WkApplication.class);//context.start();//觸發發郵件的事件
context.getBean(MailBean.class).sendMail();
}
}
5.測試結果
2. **與request 請求相關聯**
由**org.springframework.web.context.support.RequestHandledEvent**實例來表示,當在ApplicationContext中處理請求時,它們被引發。
Spring如何將事件分配給專門的監聽器?
這個過程由事件廣播器來實現,由**org.springframework.context.event.ApplicationEventMulticaster**接口的實現表示。此接口定義了3種方法
1. **addApplicationListener()** ?添加新的監聽器**:定義了兩種方法來添加新的監聽器:**addApplicationListener(ApplicationListener> listener)**和**addApplicationListenerBean(String listenerBeanName)**。當監聽器對象已知時,可以應用第一個。如果使用第二個,我們需要將bean name 得到listener對象(`依賴查找DL`),然后再將其添加到`listener`列表中
2. **removeApplicationListenerBean(String listenerBeanName)** **刪除監聽器**:添加方法一樣,我們可以通過傳遞對象來刪除一個監聽器(**removeApplicationListener(ApplicationListener> listener)**或通過傳遞bean名稱。第三種方法,**removeAllListeners()**用來刪除所有已注冊的監聽器。
3. **multicastEvent(ApplicationEvent event)****將事件發送到已注冊的監聽器**。
總結
以上是生活随笔為你收集整理的java观察者模式在spring中的应用_Spring源码之spring中的观察者模式和监听器的使用...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wstring 截取_StringUti
- 下一篇: js与java的区别,JavaScrip