1. ServletContextListener的流程筆記

        共 4398字,需瀏覽 9分鐘

         ·

        2021-08-28 16:10

        在之前我們學(xué)習(xí)springboot的時(shí)候大概的講過啟動(dòng)tomcat的過程。說到tomcat也就是servlet容器的問題,至于今天所說的ServletContextListener其實(shí)有很多的聯(lián)系。也就是說ServletServletContextListener其實(shí)是在tomcat啟動(dòng)后調(diào)用的。
        我們看一下這個(gè)接口的方法:
        public interface ServletContextListener extends EventListener {
        public default void contextInitialized(ServletContextEvent sce) { }
        public default void contextDestroyed(ServletContextEvent sce) { }}
        這么寫直接寫貌似不太友好,我們直接寫demo吧

        public class MyServletContextListener implements ServletContextListener {
        public void contextInitialized(ServletContextEvent sce) { System.out.println(sce.toString()); System.out.println("--------wo de 初始化"); }
        public void contextDestroyed(ServletContextEvent sce) { System.out.println(sce.toString()); System.out.println("--------emmm....wo死了。。。"); }}

        @Configurationpublic class MyServletConfig {    /**     * 初始化一個(gè)servlet監(jiān)聽器     * @return servlet監(jiān)聽器注冊(cè)器     */    @Bean    public ServletListenerRegistrationBean servletListenerRegistrationBean(){        ServletListenerRegistrationBean servletListenerRegistrationBean=new ServletListenerRegistrationBean();        servletListenerRegistrationBean.setListener(new MyServletContextListener());        return servletListenerRegistrationBean;    }}

        啟動(dòng)和停止的效果如下:

        功能是實(shí)現(xiàn)了,而且我們了解這塊是在tomcat啟動(dòng)的時(shí)候進(jìn)行初始化,并在tomcat停機(jī)的時(shí)候銷毀的。Spring又是如何與這ServletContextListener 結(jié)合的,tomcat如何找到這ServletContextListener 。帶著疑問我們定位到tomcat啟動(dòng)時(shí)候的server.start()方法。

                我們一路找到啟動(dòng)的方法,發(fā)現(xiàn)這塊的過濾器也是在此進(jìn)行初始化的。

        我們重點(diǎn)看一下listerner的初始化

        //獲取所有的監(jiān)聽器                Object instances[] = getApplicationLifecycleListeners();        if (instances == null || instances.length == 0) {            return ok;        }

        ServletContextEvent event = new ServletContextEvent(getServletContext()); ServletContextEvent tldEvent = null; if (noPluggabilityListeners.size() > 0) { noPluggabilityServletContext = new NoPluggabilityServletContext(getServletContext()); tldEvent = new ServletContextEvent(noPluggabilityServletContext); } for (Object instance : instances) { if (!(instance instanceof ServletContextListener)) { continue; } ServletContextListener listener = (ServletContextListener) instance; try { fireContainerEvent("beforeContextInitialized", listener); if (noPluggabilityListeners.contains(listener)) { listener.contextInitialized(tldEvent); } else { listener.contextInitialized(event); } fireContainerEvent("afterContextInitialized", listener); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); fireContainerEvent("afterContextInitialized", listener); getLogger().error(sm.getString("standardContext.listenerStart", instance.getClass().getName()), t); ok = false; } } return ok;

                我們發(fā)現(xiàn)我們的applicationContext就包括了我們的listener

            而上層調(diào)用我們的serveletlistener是誰?我們?cè)谘b配到spring上下文的時(shí)候是registerBean,那么肯定和這個(gè)類具有很大的關(guān)系。我們一直跟蹤。

                發(fā)現(xiàn)在tomcat啟動(dòng)的時(shí)候會(huì)將將所有的register傳入,并執(zhí)行onstarter方法,而每個(gè)register都自帶了其listerner之類的子成員。所以操作起來也沒有任何問題。

                我們一路跟蹤,尋找我們得beanregister是如何傳入到tomcat得啟動(dòng)代碼中。

        我們繼續(xù)向上查看。

                在創(chuàng)建tomcat服務(wù)端得時(shí)候,會(huì)將initializer作為參數(shù)傳入。而這里得initializer就是我們得ServletListenerRegistrationBean注冊(cè)器,作為spring上下文得子類,可以獲取到注冊(cè)到ioc中得得任何對(duì)象。所以這塊我們就明白了其與spring得整合原理。因?yàn)槠浔旧砭褪莝pring得一部分。

                之所以和tomcat發(fā)生了關(guān)系,是因?yàn)槲覀冊(cè)诔跏蓟脮r(shí)候?qū)pring注冊(cè)得這些servletcontextlistener、filter等等當(dāng)作參數(shù)去初始化tomcat,這就完成了從spring得bean到servlet容器得一般過程。

                上邊分析了很多,大概得過程就是那樣。這里再小結(jié)一下:我們通過@Bean注解將我們得servletlistener、filter等注冊(cè)到spring容器中,但是在tomcat初始化的時(shí)候?qū)⑦@些servlet容器需要的類通過beanfactory拿到并作為參數(shù)去初始化tomcat。從而完成bean的管理在spring中,而具體使用在tomcat中。ServletContextListener的用處還是比較廣泛的,因?yàn)楹芏鄷r(shí)候我們需要在項(xiàng)目啟動(dòng)之前做一些事情,或者在項(xiàng)目停止之后做一些事情,而且這些事情是專門針對(duì)servlet容器的這種應(yīng)用?,F(xiàn)在想一下有那些場(chǎng)景吶?比如說我們做一些異步的監(jiān)控,那么我們可以采用ServletContextListener 去創(chuàng)建定時(shí)任務(wù)線程然后去收集一些數(shù)據(jù),當(dāng)然這只是一種方式,我們也可以采用springapplicationlisenter的事件監(jiān)聽器都可以做。好了,文章就寫這里了。

        安了~



        瀏覽 44
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 免费看操逼网站 | 亚洲五月天精品无码伊人久久 | 西西444www无码大胆国产超碰 | 好看的印度三色电费 | 午夜精品久久一牛影视 |