<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                SmartLifeCycle 在LifeCycle的基礎上增加了對容器上下文的刷新感知能力。同時繼承了Phase接口提供了Bean 創建和銷毀一定的干預能力。SmartLifeCycle定義如下: ~~~ public interface SmartLifecycle extends Lifecycle, Phased { boolean isAutoStartup(); void stop(Runnable callback); } ~~~ 修改 MyLifeCycle [自定義實現Lifecycle接口](Lifecycle%E6%8E%A5%E5%8F%A3.md) 實現 SmartLifeCycle 運行輸出如下: ``` 檢查MyLifeCycle組件的運行狀態:false 容器啟動后執行MyLifeCycle操作... ==================== 檢查MyLifeCycle組件的運行狀態:true =============================== 檢查MyLifeCycle組件的運行狀態:true 收到關閉容器的信號MyLifeCycle操作... ``` 與Lifecycle 的區別是 自動調用 start方法 如果重寫 isAutoStartup 則執行結果和Lifecycle 一樣,但是執行的過程不一樣 ~~~ public boolean isAutoStartup() { return false; } ~~~ ## 關于Stop與Timeout SmartLifeCycle的stop方法傳入了一個Runnable方法,實現方是必須要調用runnable的run方法。其實查看lifecycleProcessor的默認實現DefaultLifecycleProcessor就可以知道其原因。 DefaultLifecycleProcessor中通過不同的phase進行分組排序,對于每個分組會創建一個CountdownLatch。傳入的callback中會對countdownLatch進行countdown操作。 這樣做是為了這個操作可能會采用多線程執行,需要通過countdownLatch進行并發控制,同時提供了timeout參數控制每個group的啟動以及銷毀順序。 ## onRefresh與isAutoStartup SmartLifeCycle的isAutoStartup方法用于表明bean是否希望接受onRefresh回調。如果返回true的話,那么在容器refresh的時候,就會觸發這個回調方法。Spring文檔中提到,不是每一個context都一定會實現start方法進行調用。獲取refresh回調的時候就可以提前感知而不需要等待start事件的觸發。 When the context is refreshed (after all objects have been instantiated and initialized), that callback is invoked. At that point, the default lifecycle processor checks the boolean value returned by each?SmartLifecycle?object’s?isAutoStartup()?method. If?true, that object is started at that point rather than waiting for an explicit invocation of the context’s or its own?start()?method (unlike the context refresh, the context start does not happen automatically for a standard context implementation). The?phase?value and any “depends-on” relationships determine the startup order as described earlier.《官網說明》 我們通過源碼來分析一下這個過程。Spring的ApplicationContext 構造函數中調用onRefresh方法進行容器的初始化,如下: ~~~ @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } } ~~~ 可以看到,在容器的onRefresh(context的入口)方法中,在完成了bean的加載,解析,factory的初始化,BeanFactoryPostProcessor,BeanPostProcessor,listner的注冊,以及初始化(依賴注入,bean的初始化完成)之后,調用finishRefresh方法。finishRefresh代碼邏輯如下: ~~~ protected void finishRefresh() { // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. --- 調用LifeCycle的onRefresh方法 getLifecycleProcessor().onRefresh(); // Publish the final event. ---- 發送事件廣播 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); } ~~~ 先執行LifeCycleProcessor的初始化,注冊到容器中,然后執行LifeCycleProcessor的onRefresh方法。注意,這里其實還沒有調用start方法的。所以說onRefresh是先于start的。 * **容器實現了lifeCycle接口** 我們可以發現ConfigurableApplicationContext也實現了lifeCycle接口(但此時調用LifeCycleProcessor獲取lifeCycle的接口Bean時,是沒有ConfigurableApplicationContext實現類的),context的start方法就是通過這個接口獲得的。并且context的start方法是需要創建context的調用方手動調用的,所以也就是說context的start并不會調用。而LifeCycleProcessor的start就是在context 的start中觸發的。這個也就是上面官方文檔里面說到的,start對于context并不一定會實現以及進行調用。 這個是需要十分關注的點。就是對于容器context來說,onRefresh是創建context實例的構造函數就會調用的。而start需要通過實現了lifeCycle接口的context才會具有這個能力,并且還需要client主動調用start方法,lifeCycle的start方法才會被調用。 * SmartLifeCycle與事件監聽機制 通過實現ApplicationListener接口,可以獲取容器的生命周期事件通知。 ~~~ public interface ApplicationListener<E extends ApplicationEvent\> extends EventListener { /** * Handle an application event. * @param event the event to respond to */ void onApplicationEvent(E event); } ~~~ 與事件監聽的方式感知容器事件的方式相比,實現SmartLifeCycle接口可以獲取整個生命周期的能力,包括啟動和關閉等各個方法的回調。事件監聽的廣播可以看到其實和lifeCycle的調用是前后調用的。事件監聽一樣可以獲取容器的各個階段的事件,但是需要判斷事件的類型處理不同的事件邏輯。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看