塑料機(jī)械怎么做網(wǎng)站百度的網(wǎng)站網(wǎng)址
文章目錄
- 什么是Spring事件監(jiān)聽機(jī)制
- 主要組件
- 內(nèi)置的事件監(jiān)聽類
- 自定義事件監(jiān)聽類
- 總結(jié)
前些天發(fā)現(xiàn)了一個(gè)巨牛的人工智能學(xué)習(xí)網(wǎng)站,通俗易懂,風(fēng)趣幽默,忍不住分享一下給大家。點(diǎn)擊跳轉(zhuǎn)到網(wǎng)站。
什么是Spring事件監(jiān)聽機(jī)制
Spring事件監(jiān)聽機(jī)制是Spring框架中的一種設(shè)計(jì)模式,主要用于處理應(yīng)用程序的各種事件。這種機(jī)制基于發(fā)布-訂閱設(shè)計(jì)模式,允許將業(yè)務(wù)邏輯解耦,并能更好地組織和管理代碼。
使用 Spring 事件監(jiān)聽機(jī)制的好處:
- 解耦:通過將事件的響應(yīng)邏輯交給監(jiān)聽器處理,可以將事件源和監(jiān)聽器解耦,降低代碼的耦合度。
- 可擴(kuò)展性:可以添加新的監(jiān)聽器來處理新的事件類型,而無需修改原有代碼。
- 可重用性:相同類型的事件可以在多個(gè)地方處理,提高了代碼的可重用性。
- 異步處理:事件監(jiān)聽機(jī)制支持異步處理,可以避免阻塞主線程,提高應(yīng)用程序的性能。
- 事件過濾:可以使用條件篩選需要處理的事件,只對(duì)符合條件的事件進(jìn)行處理。
主要組件
Spring 事件監(jiān)聽機(jī)制包括以下幾個(gè)主要組件:
- 事件源(Event Source):事件源是事件的發(fā)起者,通常是一個(gè)應(yīng)用程序中的特定組件或服務(wù)。當(dāng)事件源發(fā)生特定事件時(shí),會(huì)觸發(fā)事件的發(fā)布。
- 事件(Event):事件是事件源發(fā)出的消息,通常包含與事件相關(guān)的數(shù)據(jù)。事件可以是自定義的類,繼承自 Spring 的
ApplicationEvent
類。 - 監(jiān)聽器(Listener):監(jiān)聽器是訂閱了事件源的事件并負(fù)責(zé)處理事件的組件。監(jiān)聽器需要實(shí)現(xiàn) Spring 的
ApplicationListener
接口,并指定要監(jiān)聽的事件類型,該接口定義了一個(gè)onApplicationEvent
方法,用于處理接收到的事件。。 - 發(fā)布者(Publisher):發(fā)布者是負(fù)責(zé)將事件發(fā)布給所有注冊的監(jiān)聽器的組件。在 Spring 框架中,可以使用
ApplicationContext
的 publishEvent 方法來發(fā)布事件。 - 應(yīng)用上下文(ApplicationContext):
ApplicationContext
是Spring中的一個(gè)中心類,它提供了一個(gè)將事件發(fā)布到監(jiān)聽器的機(jī)制。
內(nèi)置的事件監(jiān)聽類
Spring框架提供了許多內(nèi)置的事件監(jiān)聽類,用于處理不同的事件。以下是一些常用的Spring事件監(jiān)聽類:
-
ContextRefreshedEvent:當(dāng)ApplicationContext被初始化或刷新時(shí)觸發(fā)??梢杂脕韴?zhí)行在應(yīng)用程序啟動(dòng)后需要進(jìn)行的初始化任務(wù)。
-
ContextStartedEvent:當(dāng)ApplicationContext被啟動(dòng)(調(diào)用start()方法)時(shí)觸發(fā)。可以用來執(zhí)行在應(yīng)用程序啟動(dòng)后需要進(jìn)行的特定任務(wù)。
-
ContextStoppedEvent:當(dāng)ApplicationContext被停止(調(diào)用stop()方法)時(shí)觸發(fā)。可以用來執(zhí)行在應(yīng)用程序停止前需要進(jìn)行的清理任務(wù)。
-
ContextClosedEvent:當(dāng)ApplicationContext被關(guān)閉(調(diào)用close()方法)時(shí)觸發(fā)??梢杂脕韴?zhí)行在應(yīng)用程序關(guān)閉前需要進(jìn)行的清理任務(wù)。
-
RequestHandledEvent:當(dāng)一個(gè)HTTP請(qǐng)求被處理完成后觸發(fā)。可以用來記錄請(qǐng)求的處理信息或進(jìn)行其他相關(guān)操作。
這些只是一些常見的事件監(jiān)聽類,實(shí)際上Spring還提供了更多的事件監(jiān)聽類,可以滿足不同場景下的需求。開發(fā)者也可以自定義事件監(jiān)聽類,繼承自ApplicationEvent,以實(shí)現(xiàn)自己的特定事件監(jiān)聽邏輯。
自定義事件監(jiān)聽類
自定義事件監(jiān)聽類之前 先來了解一下Spring事件監(jiān)聽機(jī)制的基本工作流程:
- 定義事件:事件通常是擴(kuò)展ApplicationEvent的類的對(duì)象,它包含有關(guān)事件的信息。
- 定義監(jiān)聽器:監(jiān)聽器是實(shí)現(xiàn)了ApplicationListener接口的類,被定義為處理特定事件類型的類。
- 注冊監(jiān)聽器:通過將監(jiān)聽器注冊到Spring容器中,或者手動(dòng)添加到ApplicationContext中。
- 發(fā)布事件:在需要的情況下,通過調(diào)用ApplicationContext的
publishEvent()
方法發(fā)布事件,Spring將該事件傳遞給所有匹配的監(jiān)聽器。
Spring機(jī)制基于發(fā)布-訂閱設(shè)計(jì)模式,這就像你關(guān)注了某個(gè)人,他一旦有作品更新,你就能立馬收到消息一樣。

下面舉個(gè)例子自定義一個(gè)Spring事件監(jiān)聽功能,比如你喜歡波多老師并且關(guān)注了她,波多老師一旦發(fā)布新電影你就能收到并且觀看。具體代碼如下:
- 定義事件MovieEvent
public class MovieEvent extends ApplicationEvent {private String movieName;public MovieEvent(Actor source , String movieName) {super(source);this.movieName = movieName;}public String getMovieName() {return movieName;}
}
@Data
public class Actor {private String name;}
- 定義監(jiān)聽器MovieListener
定義監(jiān)聽器有兩種方式,一是實(shí)現(xiàn) ApplicationListener接口,而是使用 @EventListener 注解。下面使用這兩種方式分別定義一個(gè)監(jiān)聽器。
@Component
public class MovieListener implements ApplicationListener<MovieEvent> {@Overridepublic void onApplicationEvent(MovieEvent event) {Actor actor = (Actor) event.getSource();String movieName = event.getMovieName();System.out.println("實(shí)現(xiàn)類監(jiān)聽器 監(jiān)聽到"+actor.getName()+" 發(fā)布了新電影,電影名字叫:"+movieName);}
}
@Component
public class MovieListener2 {@EventListenerpublic void listener(MovieEvent event) {Actor actor = (Actor) event.getSource();String movieName = event.getMovieName();System.out.println("注解監(jiān)聽器 監(jiān)聽到 "+actor.getName()+" 發(fā)布了新電影,電影名字叫:"+movieName);}
}
@EventListener注解是方法級(jí)別的注解,使用它可以在一個(gè)類中定義多個(gè)監(jiān)聽方法。
- 測試事件發(fā)布功能
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MqApplication.class)
public class RestTest {@Autowiredprivate ApplicationEventPublisher applicationEventPublisher;@Autowiredprivate ApplicationContext applicationContext;@Testpublic void testEvent(){Actor boDuo = new Actor();boDuo.setName("波多老師");MovieEvent movieEvent = new MovieEvent(boDuo , "好好學(xué)習(xí),別胡思亂想!");applicationContext.publishEvent(movieEvent);}
}
測試結(jié)果:
實(shí)現(xiàn)類監(jiān)聽器 監(jiān)聽到波多老師 發(fā)布了新電影,電影名字叫:好好學(xué)習(xí),別胡思亂想!
注解監(jiān)聽器 監(jiān)聽到 波多老師 發(fā)布了新電影,電影名字叫:好好學(xué)習(xí),別胡思亂想!
ApplicationContext 繼承了 ApplicationEventPublisher ,所以發(fā)布事件既可以通過 ApplicationEventPublisher#publishEvent() 方法,也可以通過ApplicationContext#publishEvent() 方法。
通過上面的測試結(jié)果可以發(fā)現(xiàn),兩個(gè)監(jiān)聽類最終都監(jiān)聽到了MovieEvent ,都在控制臺(tái)打印結(jié)果了。
實(shí)際上Spring的事件監(jiān)聽機(jī)制對(duì)于同一個(gè)事件的監(jiān)聽是同步的,默認(rèn)情況下是同步的。當(dāng)事件被發(fā)布時(shí),Spring會(huì)依次通知所有監(jiān)聽該事件的監(jiān)聽器,并在事件發(fā)布的同一線程中依序執(zhí)行監(jiān)聽器的處理邏輯。
這意味著,當(dāng)一個(gè)事件被觸發(fā)后,事件監(jiān)聽器的執(zhí)行是按照注冊的順序依次進(jìn)行的,前一個(gè)監(jiān)聽器完成后才會(huì)執(zhí)行下一個(gè)監(jiān)聽器。只有當(dāng)所有監(jiān)聽器都執(zhí)行完畢后,事件發(fā)布者才會(huì)繼續(xù)往下執(zhí)行。
如果想實(shí)現(xiàn)異步可以在監(jiān)聽器的方法上添加@Async注解,或在配置文件中進(jìn)行相應(yīng)的配置,可以使監(jiān)聽器的處理邏輯在不同的線程中執(zhí)行,從而實(shí)現(xiàn)異步處理。
如果是想實(shí)現(xiàn)監(jiān)聽器按照指定順序執(zhí)行,可以使用 @Order 注解,@Order注解的值越小,優(yōu)先級(jí)越高,即執(zhí)行順序越靠前。
總結(jié)
總的來說,Spring事件監(jiān)聽機(jī)制使用起來簡單方便,可以是組件之間解耦,提高了代碼的可維護(hù)性和可擴(kuò)展性。當(dāng)需要使用監(jiān)聽機(jī)制的時(shí)候,Spring的事件監(jiān)聽機(jī)制是個(gè)很好的選擇之一。