<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Spring 中的Event機制

      spring

      參考資料:
      Additional Capabilities of the ApplicationContext- https://docs.spring.io/spring-framework/reference/6.1/core/beans/context-introduction.html

      [[17.行為型 - 觀察者模式 (Observer Pattern)]]
      [[Spring IOC 源碼學習總筆記]]

      Spring Event

      Standard and Custom Events

      Event handling in the ApplicationContext is provided through the ApplicationEvent class and the ApplicationListener interface. If a bean that implements the ApplicationListener interface is deployed into the context, every time an ApplicationEvent gets published to the ApplicationContext, that bean is notified. Essentially, this is the standard Observer design pattern.

      簡而言之 兩點:

      1. 推送到 ApplicationContext 中的事件, 都通知容器中實現(xiàn) ApplicationEvent 接口的 bean.
      2. this is the standard Observer design pattern 它是標準的觀察者模式

      觀察者模式和發(fā)布-訂閱模式

      觀察者模式的別名有發(fā)布-訂閱(Publish/Subscribe)模式, 我們來看一下觀察者模式與發(fā)布訂閱模式結構上的區(qū)別

      • 在設計模式結構上,發(fā)布訂閱模式繼承自觀察者模式,是觀察者模式的一種 實現(xiàn)的變體。
      • 在設計模式意圖上,兩者關注點不同,一個關心數(shù)據(jù)源,一個關心的是事件消息。

      截圖_2025-11-04_22-24-18

      對比標準的觀察者模式:

      • 觀察者模式:數(shù)據(jù)源直接通知訂閱者發(fā)生改變
      • 發(fā)布訂閱模式:數(shù)據(jù)源(被觀察者) 告訴第三方(Event Channel) 發(fā)生了改變,第三方(Event Channel)再通知/廣播訂閱者(觀察者) 發(fā)生了改變

      Spring 其實基于是發(fā)布訂閱模式, 主要由ApplicationEventMulticaster 管理訂閱者/事件通道/廣播事件;

      事件模型的關鍵角色對象

      1.ApplicationEvent 事件源(中間傳遞參數(shù))

      事件源對象, 在事件中傳遞的中間參數(shù)

      org.springframework.context.ApplicationEvent

      public abstract class ApplicationEvent extends EventObject {// 它繼承了 java.util.EventObject
      	
      	/***
      	定義在 java.util.EventObject 中, 可以通過該方法獲取到事件源對象
      	public Object getSource() {  
      		return this.source;
      	}
      	***/
      	
      	/**  
      	* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}  
      	* set to {@link System#currentTimeMillis()}.  
      	* @param source the object on which the event initially occurred or with  
      	* which the event is associated (never {@code null})  
      	* @see #ApplicationEvent(Object, Clock)  
      	*/  
      	public ApplicationEvent(Object source) {  
      		super(source);  
      		this.timestamp = System.currentTimeMillis();  
      	}
      	
      	/**  
      	* Return the time in milliseconds when the event occurred.  
      	* 返回事件發(fā)生時間
      	* @see #ApplicationEvent(Object)  
      	* @see #ApplicationEvent(Object, Clock)  
      	*/  
      	public final long getTimestamp() {  
      		return this.timestamp;  
      	}
      	
      }
      

      2.ApplicationListener 監(jiān)聽器

      充當 '觀察者' 角色

      org.springframework.context.ApplicationListener

      @FunctionalInterface  
      public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {  
      	  
      	/**  
      	* Handle an application event.  
      	* 處理事件的方法.
      	* @param event the event to respond to  
      	*/  
      	void onApplicationEvent(E event);
      	
      	...
      }
      

      3.ApplicationEventPublisher 事件推送器

      充當 '被觀察者' 角色

      @FunctionalInterface  
      public interface ApplicationEventPublisher {
      
      	/**  
      	* Notify all <strong>matching</strong> listeners registered with this  
      	* application of an event.  
      	* <p>If the specified {@code event} is not an {@link ApplicationEvent},  
      	* it is wrapped in a {@link PayloadApplicationEvent}.  
      	* <p>Such an event publication step is effectively a hand-off to the  
      	* multicaster and does not imply synchronous/asynchronous execution  
      	* or even immediate execution at all. Event listeners are encouraged  
      	* to be as efficient as possible, individually using asynchronous  
      	* execution for longer-running and potentially blocking operations.  
      	* @param event the event to publish  
      	* @since 4.2  
      	* @see #publishEvent(ApplicationEvent)  
      	* @see PayloadApplicationEvent  
      	*/  
      	void publishEvent(Object event);  
        
      }
      

      4.ApplicationEventMulticaster 事件廣播器

      **充當 第三方(Event Channel) 角色, 它通知/廣播 消息給觀察者

      管理/廣播/群發(fā)事件, 注冊事件監(jiān)聽器, 管理事件通道, spring 其實最終是委托給該對象廣播事件的

      org.springframework.context.event.ApplicationEventMulticaster

      /**
      * Interface to be implemented by objects that can manage a number of
      **/
      public interface ApplicationEventMulticaster {  
        
      /**  
      * Add a listener to be notified of all events.  
      * @param listener the listener to add  
      * @see #removeApplicationListener(ApplicationListener)  
      * @see #removeApplicationListeners(Predicate)  
      */  
      void addApplicationListener(ApplicationListener<?> listener);  
        
      /**  
      * Add a listener bean to be notified of all events.  
      * @param listenerBeanName the name of the listener bean to add  
      * @see #removeApplicationListenerBean(String)  
      * @see #removeApplicationListenerBeans(Predicate)  
      */  
      void addApplicationListenerBean(String listenerBeanName);  
        
      /**  
      * Remove a listener from the notification list.  
      * @param listener the listener to remove  
      * @see #addApplicationListener(ApplicationListener)  
      * @see #removeApplicationListeners(Predicate)  
      */  
      void removeApplicationListener(ApplicationListener<?> listener);  
        
      /**  
      * Remove a listener bean from the notification list.  
      * @param listenerBeanName the name of the listener bean to remove  
      * @see #addApplicationListenerBean(String)  
      * @see #removeApplicationListenerBeans(Predicate)  
      */  
      void removeApplicationListenerBean(String listenerBeanName);  
        
      /**  
      * Remove all matching listeners from the set of registered  
      * {@code ApplicationListener} instances (which includes adapter classes  
      * such as {@link ApplicationListenerMethodAdapter}, e.g. for annotated  
      * {@link EventListener} methods).  
      * <p>Note: This just applies to instance registrations, not to listeners  
      * registered by bean name.  
      * @param predicate the predicate to identify listener instances to remove,  
      * e.g. checking {@link SmartApplicationListener#getListenerId()}  
      * @since 5.3.5  
      * @see #addApplicationListener(ApplicationListener)  
      * @see #removeApplicationListener(ApplicationListener)  
      */  
      void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate);  
        
      /**  
      * Remove all matching listener beans from the set of registered  
      * listener bean names (referring to bean classes which in turn  
      * implement the {@link ApplicationListener} interface directly).  
      * <p>Note: This just applies to bean name registrations, not to  
      * programmatically registered {@code ApplicationListener} instances.  
      * @param predicate the predicate to identify listener bean names to remove  
      * @since 5.3.5  
      * @see #addApplicationListenerBean(String)  
      * @see #removeApplicationListenerBean(String)  
      */  
      void removeApplicationListenerBeans(Predicate<String> predicate);  
        
      /**  
      * Remove all listeners registered with this multicaster.  
      * <p>After a remove call, the multicaster will perform no action  
      * on event notification until new listeners are registered.  
      * @see #removeApplicationListeners(Predicate)  
      */  
      void removeAllListeners();  
        
      /**  
      * Multicast the given application event to appropriate listeners.  
      * <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)}  
      * if possible as it provides better support for generics-based events.  
      * @param event the event to multicast  
      */  
      void multicastEvent(ApplicationEvent event);  
        
      /**  
      * Multicast the given application event to appropriate listeners.  
      * <p>If the {@code eventType} is {@code null}, a default type is built  
      * based on the {@code event} instance.  
      * @param event the event to multicast  
      * @param eventType the type of event (can be {@code null})  
      * @since 4.2  
      */  
      void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);  
        
      }
      

      內置的事件類型

      官方文檔 - Standard and Custom Events

      public class BusinessService implements ApplicationListener {
      	@Override  
      	public void onApplicationEvent(ApplicationEvent event) {  
      	    if(event instanceof ContextRefreshedEvent) {  
      		    //容器啟動完成事件  
      		}else if(event instanceof ContextClosedEvent) {  
      			//容器關閉事件
      		    excutor.shutdownNow();  
      		    log.info("業(yè)務線程池終止");  
      		}
      	}
      }
      
      • ContextRefreshedEvent ApplicationContext容器初始化或刷新觸發(fā)該事件。此處說的初始化,是指所有的bean被成功加載,后處理的bean被檢測激活,所有的singleton bean被預初始化,ApplicationContext容器已就緒可用。容器完整可用

      • ContextStartdEvent: 當使用ApplicationContext的子接口ConfigurableApplicationContex接口的start()方法啟動ApplicationContext容器時觸發(fā)該事件。容器管理生命周期的bean實例將獲得一個指定的啟動信號,這在經(jīng)常需要停止后重新啟動的場合比較常見。

      • ContextClossedEvent:當使用ConfigurableApplicationContex接口的close()方法關閉ApplicationContext容器時觸發(fā)該事件。

      • ContextStoppedEvent:當使用ConfigurableApplicationContex接口的stop()方法使ApplicationContext容器停止時觸發(fā)該事件 。此處的“停止”意味著,容器管理生命周期的bean實例將獲得一個指定的停止信號。被停止的spring容器可以再次通過調用start()方法重新啟動。

      • RequestHandledEventWeb:相關的事件,只能應用于使用DispatcherServlet的Web應用中。在使用spring作為前端的MVC控制器時,當spring處理用戶請求結束后,系統(tǒng)會自動觸發(fā)該事件。

      自定義事件實例

      EventObject 事件定義

      定義事件,繼承 ApplicationEvent 的類成為一個事件類

      @Data  
      @ToString  
      public class OrderProductEvent extends ApplicationEvent {  
        
        /** 該類型事件攜帶的信息 */  
        private String orderId;  
        
        public OrderProductEvent(Object source, String orderId) {  
          super(source);  
          this.orderId = orderId;  
        }  
      }
      

      Listener 監(jiān)聽定義

      監(jiān)聽并處理事件,實現(xiàn) ApplicationListener 接口或者使用 @EventListener 注解

      @Slf4j  
      @Component  
      public class OrderProductListener implements ApplicationListener<OrderProductEvent> {  
        
        /** 使用 onApplicationEvent 方法對消息進行接收處理 */  
        @SneakyThrows  
        @Override  
        public void onApplicationEvent(OrderProductEvent event) {  
          String orderId = event.getOrderId();  
          long start = System.currentTimeMillis();  
          Thread.sleep(2000);  
          long end = System.currentTimeMillis();  
          log.info("{}:校驗訂單商品價格耗時:({})毫秒", orderId, (end - start));  
        }  
      }
      

      在 監(jiān)聽器(Listener) onApplicationEvent 中的線程與 發(fā)布(push)線程 不是同一個線程, 它們的 ThreadLocal上下文是??完全隔離的??。不?繼承原有事務。

      Push 推送定義

      如何自定義push事件?
      使用 ApplicationEventPublisherApplicationContext 都可

      //@Autowired
      //ApplicationEventPublisher publisher;
      
      @Autowired
      ApplicationContext applicationContext;
      
      public void publish(String msg){
      	applicationContext.publishEvent(new OrderProductEvent());
      }
      
      posted @ 2025-11-04 22:25  daidaidaiyu  閱讀(6)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲av成人无网码天堂| 国产成人精品永久免费视频| 国产高清一区二区不卡| 国产成人精品无缓存在线播放| 日韩一区二区三区三级| 欧美激情 亚洲 在线| 国产成人啪精品视频免费软件| 亚洲色偷偷色噜噜狠狠99| 国产欧美精品一区aⅴ影院| 漂亮的保姆hd完整版免费韩国 | 亚洲成av人片无码迅雷下载| 宁南县| 99在线精品国自产拍中文字幕| gogogo高清在线播放免费| 亚洲一本二区偷拍精品| 国产成人高清亚洲综合| 污网站在线观看视频| 国内精品伊人久久久久AV一坑| 久久国产成人av蜜臀| 蜜臀av午夜精品福利| 制服jk白丝h无内视频网站| 欧洲免费一区二区三区视频| 丝袜美腿亚洲综合第一页| 亚洲毛片多多影院| 精品无码国产一区二区三区av| 亚洲国产成人精品av区按摩| 人人妻碰人人免费| 伊人色综合一区二区三区影院视频| 香港| 麻花传媒在线观看免费| 久久精品国产久精国产69| 99热成人精品热久久66| 亚洲一区二区日韩综合久久| 国产精品办公室沙发| FC2免费人成在线视频| 岛国最新亚洲伦理成人| 又黄又爽又色的少妇毛片| 女人喷水高潮时的视频网站| 亚洲欧洲日韩国内高清| 长腿校花无力呻吟娇喘| 国产深夜福利视频在线|