前一篇文章講了Spring中的事件驅動模型相關概念。重點篇幅介紹了Spring的事件機制,Spring的事件驅動模型由事件、發佈者和訂閱者三部分組成,結合Spring的源碼分析了這三部分的定義與實現。本文主要結合具體例子講解Spring中的事件驅動。筆者在寫Spring Cloud Bus中的事件的訂閱與發佈兩篇文章的時候,想到要把Spring中的事件驅動模型的講解給補充一下,這塊也是屬於更加基礎的知識點。java
咱們示例配置信息的刷新,當配置服務器收到提交的配置事件以後,將會觸發各個服務響應的更新本身的配置。具體代碼以下:spring
public class ConfigRefreshEvent extends ApplicationEvent {
public ConfigRefreshEvent(final String content) {
super(content);
}
}
複製代碼
定義一個配置刷新的事件。繼承ApplicationEvent
便可,content即爲須要傳遞的object。bash
定義兩個服務,都實現了SmartApplicationListener
,該接口繼承自ApplicationListener
和Ordered
接口,屬於標準監聽器的擴展接口,公開更多的元數據,例如支持的事件類型和可排序的監聽器。服務器
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
/** * 決定該監聽器是否支持給定的事件 */
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
/** * 決定該監聽器是否支持給定的目標類型,支持纔會調用 */
boolean supportsSourceType(Class<?> sourceType);
}
複製代碼
下面貼出兩個Service的代碼。微信
@Component
public class ServiceAListener implements SmartApplicationListener {
@Override
public boolean supportsEventType(final Class<? extends ApplicationEvent> eventType) {
return eventType == ConfigRefreshEvent.class;
}
@Override
public boolean supportsSourceType(final Class<?> sourceType) {
return sourceType == String.class;
}
@Override
public void onApplicationEvent(final ApplicationEvent event) {
System.out.println("ServiceA收到新的配置:" + event.getSource());
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
複製代碼
@Component
public class ServiceBListener implements SmartApplicationListener {
@Override
public boolean supportsEventType(final Class<? extends ApplicationEvent> eventType) {
return eventType == ConfigRefreshEvent.class;
}
@Override
public boolean supportsSourceType(final Class<?> sourceType) {
return sourceType == String.class;
}
@Override
public void onApplicationEvent(final ApplicationEvent event) {
System.out.println("ServiceB收到新的配置:" + event.getSource());
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
複製代碼
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testPublishEvent() {
System.out.println("發佈配置更新:");
ConfigRefreshEvent event = new ConfigRefreshEvent("配置信息更新了")
applicationContext.publishEvent(event);
}
}
複製代碼
上面是咱們的測試類,至關於事件的發佈者,首先定義一個配置刷新的事件,而後經過注入的ApplicationContext
發佈該事件。app
因爲ServiceA的優先級高於ServiceB,因此咱們看到以下的結果:ide
發佈配置更新:
ServiceA收到新的配置:配置信息更新了
ServiceB收到新的配置:配置信息更新了
複製代碼
本文比較簡單,在上一篇介紹Spring中的事件驅動模型基礎上,具體應用到配置刷新的場景中。Spring的事件驅動模型使用的是觀察者模式。經過ApplicationEvent
抽象類和ApplicationListener
接口,能夠實現事件的定義與監聽,ApplicationContext
則實現了事件的發佈。例子中使用的SmartApplicationListener
擴展了標準的事件監聽接口,監聽器在處理Event時,能夠對傳入的Event進行判斷,而且能夠設定監聽器的優先級。後面抽時間會寫一下 Spring Cloud 的熱更新機制,也是基於Spring中的事件驅動模型。源碼分析