澳洲森林大火 空污程度空前

摘錄自2019年11月22日中央通訊社澳洲報導

澳洲新南威爾斯省遍布森林野火,飄散出的煙霧使今天(22日)空污程度空前,造成就醫人數激增,並引起駕駛人視線不良等危險。

澳洲人口第一大城雪梨(Sydney)已連續4天被煙霧籠罩,罕見但一再成為世界空污最嚴重的10大城市之一。近幾天來某些時候,全球城市空氣品質監測網站Air Visual排行顯示,雪梨名列世界空污最嚴重的第8大城市,排名在雅加達及深圳之前,位居孟買之後。

隨著強風吹送林火煙霧以及因全澳3年乾旱而堆積的灰塵,波克鎮的空污比安全標準高出15倍。煙霾挾帶著來懸浮微粒污染物,形成官員所說新南威爾斯省紀錄中的最嚴重污染。這種粒子會被人體吸入血液中。

大火迄今仍在新南威爾斯省、維多利亞省(Victoria)、南澳省(South Australia)及昆士蘭省(Queensland)燃燒。澳洲總理莫里森(Scott Morrison)因為這次危機而受到壓力,批評者指稱,莫里森並未盡力處理氣候變遷的衝擊。氣象學家則指出,氣候變遷正導致野火季節的時間延長。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

馬來西亞最後一頭蘇門答臘犀牛病逝 全球剩80頭

摘錄自2019年11月24日中央通訊社馬來西亞報導

馬來西亞最後一隻蘇門答臘犀牛,25歲的母犀牛伊曼自2014年被捕獲後,一直在野生動物保護區接受妥善照顧,牠今天(24日)因癌病逝於婆羅洲(Borneo)沙巴(Sabah)。沙巴野生動物部門(Sabah Wildlife Department)主任奧古斯丁(Augustine Tuuga)說:「伊曼的死亡比預期要快,但我們知道,牠已經開始承受極大痛苦。」

蘇門答臘犀牛是體型最小的犀牛,曾廣布亞洲各地,野生蘇門答臘犀牛如今已近乎絕種,據保育人士估計,目前全球僅剩約30至80頭,大多棲息在蘇門答臘和印尼所管轄的婆羅洲地區。馬來西亞2015年宣布野生蘇門答臘犀牛絕種,最後一頭公蘇門答臘犀牛今年5月離世。

保育團體國際犀牛基金會(International Rhino Foundation)說,棲地減少和盜獵導致蘇門答臘犀牛生存於孤立區域,代表牠們繁衍困難,數十年內可能就會滅絕。

自2011年以來,馬來西亞不斷嘗試以體外受精方式,繁殖人工飼養的蘇門答臘犀牛,但迄今尚未成功。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

違法噴灑遭禁殺蟲劑 孟山都將付3億罰款

摘錄自2019年11月22日中央通訊社美國報導

美國農業生技巨擘孟山都(Monsanto)今天(22日)同意認罪,承認在夏威夷毛伊島(Maui)的設施對研究作物違法噴灑遭禁的劇毒殺蟲劑,將支付1000萬美元(約新台幣3億532萬元)罰款。

法新社報導,孟山都在提交給檀香山聯邦地區法院的法庭文件中承認,2014年在農場谷(Valley Farm)對玉米種子等作物噴灑Penncap-M殺蟲劑,即使已知環境保護署於2013年禁用這款化學物。

審理此案的加州中區聯邦檢察官韓納(Nick Hanna)說:「此案的違法行徑對環境、周圍社區和孟山都工人構成威脅。」他說:「聯邦法律與相關規範規定,使用管制和危險化學物的每個人,都有責任確保產品是經過安全儲存、運送與使用。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家前需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

新宿市民測定所 發表嬰幼兒奶粉輻射檢查報告

文:宋瑞文(媽媽監督核電廠聯盟特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

Tesla 挹注擴大 F-貿聯第三季營收季增幅度大

Tesla 日前發表的儲能電池計畫,受到外界關注,法人評估,首波供應商 F-貿聯最快 8 月有機會開始交貨,明年下半年新計畫挹注逐步擴大。法人也預估,該公司本季營收季增個位數、且將挑戰單季新高,第三季起隨 Tesla 新 SUV 車款問世,6 月下旬起零件逐月放量,下季營收季增幅度將拉大,全年營收拚增兩位數。   F-貿聯與 Tesla 的往來關係深厚,早在 Tesla 還未成為全球知名的電動車大廠前,就已相互搭配,因此也成為該客戶的指標核心供應商。一直以來,貿聯較為人熟知是 Tesla 電動車電池管理系統線束的獨家供應商,此次配合與松下合資的超級電池工廠明年下半年量產,電池供應量將大增。   據了解,F-貿聯已是特斯拉除能電池系統 Powerwall 與企業用 Powerpack 計畫的首波零件供應商,供貨品項仍為電池管理系統用線。法人預期,最快 8 月有望正式交貨,雖對今年的營收貢獻不大,但更確認了貿聯在 Tesla 各項計畫共同開發的核心地位,而明年下半年超級電池工廠如果順利量產,該計畫的挹注將明顯增溫。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

北汽與Amber Dual合資逾2億人民幣 建馬來西亞電動車工廠

據馬來西亞媒體5月19日報導,北汽集團近日在其北京工廠與Amber Dual有限公司簽訂了合資協議,雙方將投資2-3億元人民幣,在馬來西亞吉打州建立一座新廠,並將耗資約5,000萬元人民幣用於研發,預計於明年7月份開始生產。   此馬來西亞廠將作為北汽在東南亞地區的電動車生產中心。北汽為該工廠設定的電動車年產量目標為2,000到3,000輛,此後將逐漸遞增。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

※別再煩惱如何寫文案,掌握八大原則!

三次握手四次揮手

一直都知道 TCP 建立連接時需要三次握手,釋放連接時需要四次揮手,也大概能說出整個過程,但是一直對其中的設計思想理解不深,停留在“只可意會,不可言傳”的階段。這次寫一篇博客嘗試將其中的思想表達出來。

 

 

 

TCP 建連三次握手

首先解釋一下每個步驟的作用:
1、a 時刻,A 準備就緒,發送 SYN 包給 B,嘗試建立連接
2、b 時刻,B 收到 A 發來的 SYN 包,知道 A 要請求建連,回 SYN ACK 包,告訴 A 自己收到了建連請求,可以建連了
3、c 時刻,A 收到了 B 的回復,知道 B 準備好了,鏈路通暢,可以發送數據了。回  ACK 告知 B 收到了 B 的回復,下面要開始發送該數據了
4、d 時刻,B 收到了 A 的回復,知道 A 接下來要發數據了。至此,AB 雙方都確認整個鏈路已經可靠了,接下來可以發送數據了。

 

為什麼要多次確認呢?為什麼不可以 A 上來就直接發送數據給 B 呢?
這裏首先要明確一點,TCP 是傳輸層的協議,是建立在物理層、數據鏈路層、網絡層之上的協議,而底層的網絡是不可靠的,可能路由出問題,可能網關出問題,可能網線出問題,A 沒法保證自己發出來的消息 B 一定能收到,所以一定要反饋機制,即 ACK,這樣才能在不可靠的網絡層智商構建可靠的傳輸層。

 

類比一下生活中的例子,可以幫助我們理解
示例1,假設我們在火車上打電話,通話質量很差,我們的通話過程可能會是下面這樣:

 

 

AB 雙方首先需要確認彼此都能挺到對方的聲音,也就是保證電話通道是可靠的,之後才會開始說正事。如果一上來就直接說正事,可能 A 說完之後 B 根本就沒有聽到。
實際打電話過程中,如果遇到了斷線的情況,雙方可能需要進行多次“握手”確認。

 

示例2,假設我們給剛認識的人第一次打電話,通話過程可能是下面這樣:

 

 

AB 雙方都要確認對方的身份,也就是保證通話是在跟自己人進行,確保電話通道是可靠的,不是跟騙子通話,然後才會開始說正事。如果一上來沒有確認身份,不能保證通道是跟自己人進行的,那直接說出重要的事,很可能就泄漏了機密。

 

總之,握手過程的最終目的就是保證雙方都準備就緒,通路是可靠的,之後就可以放心的發送重要數據了。

 

那為什麼一定是三次呢,為什麼不是兩次或者四次呢?
先來說一下為什麼不能少。
一次可以嗎?不可以。設想一下,A 對 B 說:我要給你發數據。然後不等 B 的回復,接下來就開始發數據了。這時候根本不能保證 B 已經準備好了,那 A 發出來的數據就沒法保證 B 一定能收到。聯想生活中的場景,你隔着很遠的距離向對方喊話:我要把蘋果扔給你。然後不關心對方有沒有聽到,就直接扔了,那最終的結果通常就是對方接不到蘋果,因為對方可能根本沒有收到消息。
兩次可以嗎?不可以。設想一下,A 對 B 說:我要給你發數據,然後 B 收到消息后給 A 回復:收到,A 在收到 B 的回復后開始發送數據。這時候 A 端是可以準備就緒的,但是 B 端不知道 A 端當前的狀態。因為 B 在收到 A 的消息的時候,可能已經過去了很長時間,B 在回消息的時候,A 可能已經不在線了,此時 B 是不能直接發數據的。如果 A 再給 B 回一個 ACK,B 就可以確認當前鏈路狀態了,這就變成了三次握手。

接下來說一下為什麼不是四次。既然三次已經可以保證建立可靠通信,就不需要額外的一次交互了。

 

下面是幾個生活中相關的示例:

 

 

 

 

 

 

 

 

 

 

 TCP 斷鏈四次揮手
1、a 時刻,A 向 B 發出 FIN 包,表示自己沒有數據要發送了
2、b 時刻,B 收到 FIN 包,回復 FIN ACK,表示收到了 A 的 FIN 包,不會再接收 A 的數據了
3、B 在發完 FIN ACK 后,可能還有數據要發給 A,這個數據是不能停止發送的,有數據還是需要繼續發送
4、d 時刻,B 發完了數據,也發出 FIN 包,告訴 A 自己的數據發完了,不再發送數據了
5、e 時刻,A 收到了 B 的 FIN 包,知道 B 也沒有數據要發送了,回復 FIN ACK。此時,連接可以斷開了

建連只需要交互三次,斷連卻需要四次,這是為什麼呢?其實斷開連接和建立連接還是不一樣的。建連的時候,只要雙方都告知對方自己準備好了就可以,但是斷連的時候,一方提出要斷開連接,不再發數據,另一方不能立即斷開,因為這一方可能還有數據要發送,直到數據全部發送完成后才能確認斷開。

 

下面是幾個生活中相關的示例:

 

 

 

以上是對於三次握手、四次揮手的簡單介紹,裏面沒有更詳細的狀態介紹,之後的博客會介紹,這裏先放兩張圖。
TCP 三次握手

 

 

 

TCP 四次揮手
 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

【Spring】內嵌Tomcat&去Xml&調試Mvc

菜瓜:今天聽到個名詞“父子容器”,百度了一下,感覺概念有點空洞,這是什麼核武器?

水稻:你說的是SpringMvc和Spring吧,其實只是一個概念而已,用來將兩個容器做隔離,起到解耦的作用,其中子容器可以拿到父容器的bean,父容器拿不到子容器的。但是SpringBoot出來之後這個概念基本就被淡化掉,沒有太大意義,SpringBoot中只有一個容器了。

菜瓜:能不能給個demo?

水稻:可以。由於現在SpringBoot已經大行其道,Mvc你可能接觸的少,甚至沒接觸過。

  • 早些年啟動一個Mvc項目費老鼻子勁了,要配置各種Xml文件(Web.xml,spring.xml,spring-dispather.xml),然後開發完的項目要打成War包發到Tomcat容器中
  • 現在可以直接引入Tomcat包,用main方法直接調起。為了調試方便,我就演示一個Pom引入Tomcat的例子
  • ①啟動類
  • package com.vip.qc.mvc;
    
    import org.apache.catalina.Context;
    import org.apache.catalina.LifecycleException;
    import org.apache.catalina.LifecycleListener;
    import org.apache.catalina.startup.Tomcat;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    
    /**
     * 參考: * https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-servlet
     * <p>
     * 嵌入tomcat,由Tomcat發起對Spring容器的初始化調用過程
     * <p>
     * - 啟動過程
     * * - Servlet規範,Servlet容器在啟動之後會SPI加載META-INF/services目錄下的實現類並調用其onStartup方法
     * * - Spring遵循規範實現了ServletContainerInitializer接口。該接口在執行時會收集WebApplicationInitializer接口實現類並循環調用其onStartup方法
     * * - 其中AbstractDispatcherServletInitializer
     * * * - 將spring上下文放入ContextLoaderListener監聽器,該監聽會發起對refresh方法的調用
     * * * - 註冊dispatcherServlet,後續會由tomcat調用HttpServletBean的init方法,完成子容器的refresh調用
     * *
     *
     * @author QuCheng on 2020/6/28.
     */
    public class SpringWebStart {
    
        public static void main(String[] args) {
            Tomcat tomcat = new Tomcat();
            try {
                // 此處需要取一個目錄
                Context context = tomcat.addContext("/", System.getProperty("java.io.tmpdir"));
                context.addLifecycleListener((LifecycleListener) Class.forName(tomcat.getHost().getConfigClass()).newInstance());
                tomcat.setPort(8081);
                tomcat.start();
                tomcat.getServer().await();
            } catch (LifecycleException | ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
            }
        }
    
    
        static class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
            private final static String PACKAGE_PATH = "com.vip.qc.mvc";
    
            @Override
            protected String[] getServletMappings() {
                return new String[]{"/"};
            }
    
            @Override
            protected Class<?>[] getRootConfigClasses() {
                // spring 父容器
                return new Class[]{AppConfig.class};
            }
    
            @Override
            protected Class<?>[] getServletConfigClasses() {
                // servlet 子容器
                return new Class[]{ServletConfig.class};
            }
    
            @ComponentScan(value = PACKAGE_PATH,
                    excludeFilters = {
                            @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class),
                            // 避免掃描到加了註解(@Configuration)的子容器
                            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ServletConfig.class)})
            static class AppConfig {
            }
    
            @ComponentScan(value = PACKAGE_PATH)
            static class ServletConfig {
            }
        }
    }
  • ②Controller&Service
  • package com.vip.qc.mvc.controller;
    
    import com.vip.qc.mvc.service.ServiceChild;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.annotation.Resource;
    
    /**
     * @author QuCheng on 2020/6/28.
     */
    @Controller
    public class ControllerT implements ApplicationContextAware {
    
        @Resource
        private ServiceChild child;
    
        @RequestMapping("/hello")
        @ResponseBody
        public String containter() {
            child.getParent();
            System.out.println("parentContainer");
            return "containter";
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            System.out.println("子容器" + applicationContext);
            System.out.println("子容器中獲取父容器bean" + applicationContext.getBean(ServiceChild.class));
        }
    }
    
    
    package com.vip.qc.mvc.service;
    
    import com.vip.qc.mvc.controller.ControllerT;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.NoSuchBeanDefinitionException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Service;
    
    /**
     * @author QuCheng on 2020/6/28.
     */
    @Service
    public class ServiceChild implements ApplicationContextAware {
    
        //    @Resource
        private ControllerT controllerT;
    
        public void getParent() {
    
            System.out.println(controllerT);
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            System.out.println("父容器" + applicationContext);
            try {
                System.out.println("父容器中獲取子容器bean" + applicationContext.getBean(ControllerT.class));
            } catch (NoSuchBeanDefinitionException e) {
                System.out.println("找不到子容器的bean");
            }
        }
    }

    // 調用
    SpringWebStart的main方法啟動-會有如下打印
    父容器Root WebApplicationContext, started on Sun Jun 28 22:03:52 CST 2020
    找不到子容器的bean
    子容器WebApplicationContext for namespace 'dispatcher-servlet', started on Sun Jun 28 22:03:58 CST 2020, parent: Root WebApplicationContext
    子容器中獲取父容器beancom.vip.qc.mvc.service.ServiceChild@4acfc43a
    
    
  • Demo比較簡單,不過也能反映父子容器的關係

菜瓜:嗯,效果看到了,能不能講一下啟動過程

水稻:稍等,我去下載源碼。上面代碼演示中已經提前說明了,父子容器的加載是Tomcat依據Servlet規範發起調用完成的

  • spring-web源碼包的/META-INF中能找到SPI的實際加載類SpringServletContainerInitializer#onStartup()方法會搜集實現WebApplicationInitializer接口的類,並調用其onStartup方法
  • 上面MyWebApplicationInitializer啟動類是WebApplicationInitializer的子類,未實現onStartup,實際調用的是其抽象父類AbstractDispatcherServletInitializer的方法。跟進去 
  • @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
       //① 創建Spring父容器上下文-對象放入ContextLoadListener,後續調起完成初始化,
       super.onStartup(servletContext);
       //② 創建DispatcherServlet對象,後續會由tomcat調用其init方法,完成子容器的初始化工作
       registerDispatcherServlet(servletContext);
    }
    
    // ①進來
    protected void registerContextLoaderListener(ServletContext servletContext) {
        // 此處會回調我們啟動類的getRootConfigClasses()方法 - 父容器配置
        WebApplicationContext rootAppContext = createRootApplicationContext();
        if (rootAppContext != null) {
            ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
            istener.setContextInitializers(getRootApplicationContextInitializers());
            servletContext.addListener(listener);
        }
        else {
            logger.debug("No ContextLoaderListener registered, as " +
                  "createRootApplicationContext() did not return an application context");
        }
    }
    
    // ②進來
    protected void registerDispatcherServlet(ServletContext servletContext) {
            。。。
        // 此處會回調我們啟動類的getServletConfigClasses()方法 - 子容器配置
        WebApplicationContext servletAppContext = createServletApplicationContext();
            。。。
        // 初始化的dispatcherServlet,會加入Tomcat容器中-後續調用
        // FrameworkServlet#initServletBean()會完成上下文初始化工作
        FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
            。。。
    }

菜瓜:這樣容器就可以用了嗎?

水稻:是的,這樣就可以直接在瀏覽器上面訪問http://localhost:8081/hello,不過這是一個最簡陋的web項目

菜瓜:懂了,最簡陋是什麼意思

水稻:如果我們想加一些常見的Web功能,譬如說攔截器,過濾器啥的。可以通過@EnableWebMvc註解自定義一些功能

  • package com.vip.qc.mvc;
    
    import com.vip.qc.mvc.interceptor.MyInterceptor1;
    import com.vip.qc.mvc.interceptor.MyInterceptor2;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import javax.annotation.Resource;
    
    /**
     * @author QuCheng on 2020/6/28.
     */
    @Configuration
    @EnableWebMvc
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Resource
        private MyInterceptor1 interceptor1;
        @Resource
        private MyInterceptor2 interceptor2;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(interceptor1).addPathPatterns("/interceptor/**");
            registry.addInterceptor(interceptor2).addPathPatterns("/interceptor/**");
        }
    }
    
    
    
    package com.vip.qc.mvc.interceptor;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author QuCheng on 2020/6/28.
     */
    @Configuration
    public class MyInterceptor1 implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("嘻嘻 我是攔截器1 pre");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("嘻嘻 我是攔截器1 post");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("嘻嘻 我是攔截器1 after");
        }
    }
    
    
    package com.vip.qc.mvc.interceptor;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author QuCheng on 2020/6/28.
     */
    @Configuration
    public class MyInterceptor2 implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("嘻嘻 我是攔截器2 pre");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("嘻嘻 我是攔截器2 post");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("嘻嘻 我是攔截器2 after");
        }
    
    } 

菜瓜:我知道,這裏還有個Mvc請求調用流程和這個攔截器有關。而且這個攔截器不是MethodInterceptor(切面)

水稻:沒錯,說到這裏順便複習一下Mvc的請求過程

  • 請求最開始都是通過Tomcat容器轉發過來的,調用鏈:HttpServlet#service() -> FrameworkServlet#processRequest() -> DispatcherServlet#doDispather()
  •  1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
     2     。。。
     3   processedRequest = checkMultipart(request);
     4   multipartRequestParsed = (processedRequest != request);
     5   // 1.返回一個持有methodHandler(按照URL匹配得出的被調用bean對象以及目標方法)調用鏈(攔截器鏈)對象
     6   mappedHandler = getHandler(processedRequest);
     7   。。。
     8   // 2.按照我們現在寫代碼的方式,只會用到HandlerMethod,其他三種基本不會用
     9   HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    10   。。。
    11   // 3.前置過濾器 - 順序調用
    12   if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    13       return;
    14   }
    15   // 4.Actually invoke the handler.
    16   mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    17   。。。
    18     applyDefaultViewName(processedRequest, mv);
    19   // 5.後置過濾器 - 逆序調用
    20   mappedHandler.applyPostHandle(processedRequest, response, mv);
    21   。。。
    22   // 6.處理試圖 - 內部render
    23   processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    24   }
    25   catch (Exception ex) {
    26      // 異常處理
    27      triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    28   }
    29       // 異常處理
    30   catch (Throwable err) {
    31      triggerAfterCompletion(processedRequest, response, mappedHandler,
    32                     new NestedServletException("Handler processing failed", err));
    33   }
    34     。。。

     

 菜瓜:這個之前看過不少,百度一大堆,不過還是源碼親切

 

總結:

  • 目前基本互聯網項目都是SpringBoot起手了,再難遇到SpringMvc的項目,不過熟悉該流程有利於我們更加深刻的理解Ioc容器
  • Mvc攔截器鏈也是日常開發中會用到的功能,順便熟悉一下請求的執行過程

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

※別再煩惱如何寫文案,掌握八大原則!

智慧充電管理軟體真的有效,加州電動交通車隊省下 40% 電費

隨著綠能推展,全球無數新創事業應運而生,宣稱智慧軟體能在能源多元化時代為顧客省錢,也包括電動車隊的智慧充電管理系統,這些系統真能達到宣稱的效益嗎?如今第一波實際使用的成果已逐漸顯現。新創事業 Amply Power 於 2020 年 4 月發表系統應用於北加州康特拉科斯塔郡 Tri Delta 交通車隊電動車的成效,自 2020 年初以來,為車隊節省了 40% 電費。

隨著都市市區環保意識上升,以及各國推動減碳,加上電池降價使得電動車購置成本降低,越來越多公車與交通車隊改用電動車,目前全球有超過 200 家交通車隊採用電動車,並預計到 2025 年電動巴士將占全球交通車隊 30%。

Tri Delta 早在 2018 年就已經開始加入潮流,當時只先測試 4 輛電動車,2 輛來自比亞迪、2 輛來自加州電動巴士廠 Proterra,即使只是先測試 4 輛,對車隊的後勤作業就造成相當大的改變。少了 4 輛車需要柴油與一般引擎車的維修,但多出與電力公司交涉、升級變電器、安裝高壓電力裝置等任務,僅 4 輛車就導致最高電力需求負載高達 300 千瓦,這下突然得處理很多過去不曾想過的電力節費問題。

於是 2019 年底 Tri Delta 決定採用 Amply Power 的智慧充電管理軟體,由軟體管理充電時間,挑選電費較低的離峰時間充電,以節省電費,但又同時確保要用車的時候電力有充飽,車隊後勤人員不再需要思考何時插上充電座比較省錢,讓軟體決定就好了。此外,改採電動車之後,最大的困擾就是一旦充電沒有插好,等到隔天要用車,車子沒電才發現,就會造成調度嚴重問題,使用充電管理軟體後,充電若沒插好,軟體會發出警告,一勞永逸解決了這個防呆問題。

充電管理結果能否擴大適用還待驗證

使用充電管理軟體的期間,Tri Delta 的電力公司太平洋瓦電(PG&E)調整過尖峰用電時間表,Tri Delta 本身用電變化也讓所屬費率區間有變動,過去這些都會造成負責充電的員工傷透腦筋,每週的最佳充電時間都不同,一不小心就讓公司承受高額電費,這些變動更顯出充電管理軟體的重要性,充電管理軟體會自動依據電力公司的時間表與公式調整,算出最划算的充電時間。

經過幾個月使用下來,Tri Delta 節省了高達 40% 電費支出,這還只是第一季,進入夏季後,尖峰用電費率落差更大,會讓充電管理的效益更明顯。

不過,這僅是 4 輛電動車的充電管理結果,能否擴大適用到上百台規模的大車隊,尚需進一步驗證。不過越大的車隊,原理上來說,充電管理能達到的效益會更顯著,不僅節省電費更多,軟體最佳化分配車輛充電的時間,更可以讓硬體投資也跟著減少,例如設置較少充電座,或讓電力設備不需太大規模升級,節省建設成本與工程時間。

Amply Power 此實證案例,不僅證明充電管理的重要性,為許多管理軟體新創事業開創市場,另一方面,也同時為整個電動車產業打了一劑定心針:電動巴士車隊雖然成本較高,但可仰賴電費比燃料費用便宜來達成經濟效益,如今這商業模式面臨挑戰,因油價在全球新冠病毒疫情影響下降到低點,電動車的費用優勢可能消失,但是,若充電管理能省下 40% 電費,那麼,電動車隊尚可取回一部分競爭優勢。

(合作媒體:。首圖來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

急轉彎!特斯拉取消提前復工,股價由漲轉跌

先前消息傳出,電動車大廠特斯拉(Tesla)要求員工於 29 日返回工作崗位,以便讓加州佛利蒙(Fremont)組裝廠恢復生產。但隨著該廠所在的舊金山灣區六郡宣佈延長居家禁令,特斯拉政策急轉彎,已通知員工無需提前復工。

CNBC 報導,根據特斯拉的內部信件,24 日和週末,特斯拉管理層要求數十名員工於 29 日重返工作崗位,讓佛利蒙廠產線重啟運作。不過,由於舊金山灣區六郡(舊金山、聖克拉拉、聖馬刁、馬林、康特拉哥斯,以及佛利蒙廠所在的阿拉米達郡)27 日宣佈,將「就地避難」(shelter-in-place)令的期限由 5 月 4 日延長至 5 月底,特斯拉隨後也取消本週的復工計畫。

特斯拉人力資源部週一發送內部訊息向員工表示:「按照執行領導團隊的指示,我們將不會在 4 月 29 日星期三恢復工作。請忽略關於本週復工的所有訊息和指示。」

報導指出,特斯拉佛利蒙廠生產 Model S 和 Model X 車型,以及較新的 Model 3 和 Model Y 車型,銷往北美和歐洲市場。位於中國上海的組裝廠,先前也因疫情短暫關閉約兩週,但在當地政府的協助下迅速恢復運作,目前每週營運 6 天。

在佛利蒙廠有望提前復工的利多消息帶動下,27 日特斯拉股價大漲 10.15% 收 798.75 美元,但取消復工的消息公佈後,盤後股價挫跌 2.10% 至 782.00 美元。今年以來,特斯拉股價累計飆漲 90.98%。

《華爾街日報》先前報導,根據特斯拉 4 月 2 日資料,2020 年第一季交車數達 88,400 輛,較去年同期成長 40%,雖然疫情導致整體車市市況不振,但特斯拉仍維持原先銷售目標。

今年初,特斯拉執行長馬斯克(Elon Musk)預估,特斯拉今年電動車銷量將維持強勁成長,比去年至少成長 36%,全球總交車數可望「輕鬆突破」(comfortably exceed)50 萬輛。

特斯拉預計 29 日發表 2020 年第一季財報。

(本文內文由  授權使用;首圖來源: CC BY 2.0)

延伸閱讀:

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

※別再煩惱如何寫文案,掌握八大原則!