分類
發燒車訊

中德電動汽車充電項目取得新進展 第三階段正式啟動

德國Spiegel Institut Mannheim對半公共充電樁用戶的充電和駕駛行為進行了研究,提出了提高充電效率、付費方式便捷化等建議。本研討會的另一重要議題是介紹並啟動項目第三階段的研究工作。作為項目第三階段的主要研究機構,普華永道思略特在研討會上向與會人員介紹了項目第三階段的主要課題內容和部分課題的初步研究成果。

在中德兩國政府以及大眾汽車、寶馬、戴姆勒、北汽的大力支持下,“中德電動汽車充電項目”於2016年11月8日在北京召開了第二階段總結暨第三階段啟動會。來自相關政府部門、行業協會、電力企業、中德車企和研究機構的代表出席了會議。國家發改委產業協調司机械裝備處處長吳衛和德國聯邦環境、自然保護、建築和核安全部主管排放控制,設備安全與交通司副司長Dr. Norbert Salomon出席會議並致辭。

“中德電動汽車充電項目”第二階段於2015年3月在北京啟動,於2015年12月底完成。項目選取北京地區住宅小區的公共停車區域、寫字樓、政府機關事業單位以及公共商業物業等(半)公共領域開展充電解決方案研究。參与項目運營的電動汽車包括奧迪 A3 e-tron、北汽EV200、大眾汽車electric up!、寶馬i3、奔馳Smart ED、華晨寶馬之諾1E 和騰勢。

“中德電動汽車充電項目”第二階段針對(半)公共領域充電開展了三個課題的研究,即“電動汽車用戶信息研究”、“半公共區域電動汽車充電設施商業模式實證研究”和“基於電動汽車發展的北京市(半)公共區域充電地點選擇和可行性分析”。清華大學、中國汽車技術研究中心以及德國Spiegel Institut Mannheim作為課題研究機構,在會上分別彙報了研究成果。

清華大學研究團隊以北京為例開展研究,得出的基本結論是在中國推廣半公共充電有其可行性。此外,通過對車位及充電設施使用開放度的分析,研究團隊認為,在保證合理商業運營及管理模式的前提下,對寫字樓、公共商業物業甚至是政府及事業單位中低峰時段的車位加以利用也有其可行性,值得积極探索。

中國汽車技術研究中心研究團隊從充電基礎設施商業運營模式角度,建議政府適時出檯面向運營環節的補貼、停車費用減免等政策,使半公共充電成為私人充電的有效補充和替代。同時要鼓勵運營商积極創新、嘗試新型業務和商業模式,通過擴展業務範圍及實現與其他相關業務的協同發展來拓寬收入來源,有效縮短投資回收周期。同時,中國汽車技術研究中心研究團隊也提出在半公共區域單獨報裝充電設施、建設充電專屬車位等其他相關建議。

德國Spiegel Institut Mannheim對半公共充電樁用戶的充電和駕駛行為進行了研究,提出了提高充電效率、付費方式便捷化等建議。

本研討會的另一重要議題是介紹並啟動項目第三階段的研究工作。作為項目第三階段的主要研究機構,普華永道思略特在研討會上向與會人員介紹了項目第三階段的主要課題內容和部分課題的初步研究成果。

項目第三階段的研究課題主要圍繞未來長里程電動汽車的充電需求及其與環境的相互影響。課題分為六大模塊:長里程電動車需求預測、消費者充電需求及充電行為分析、相關政策法規及技術參數分析、電動汽車發展與電力供應的相互影響、電動汽車發展對住建行業的主要影響,以及充電基礎設施發展分析等。

其中,普華永道思略特在研討會上針對“電動汽車發展與電力供應的相互影響”模塊的一些初步成果也進行了彙報與討論。普華永道思略特分析,由於中國呈現電力過剩的特點,電動汽車不但不會對發電端造成壓力,還能消耗過剩電能。從用電負荷分析,在無序充電的情景下,2020~2025年電動汽車引起的用電負荷增加量佔全國裝機量的比例較少,在全國層面造成的影響較小;當電動汽車佔比達到較高水平時,部分省市峰值用電負荷將顯著增加,為電網帶來一定壓力。另外,隨着電動汽車的發展,部分小區將出現配電系統升級的需求。

針對電網如何能夠更好地支持電動汽車產業的發展,普華永道思略特給出了三點建議:建立跨行業溝通平台,推動各利益相關方的合作,积極促進各方達成共識並提高資源利用效率;更好的發揮價格指導作用,激勵消費者,並加快發展智能化、信息化技術,實現有序充電;研究制定傳導機制,解決因電動汽車發展帶來的配電網備擴容成本問題,確保有效傳遞電力企業或者產權方承擔的成本增加。

最後,中德雙方均對“中德電動汽車充電項目”第二階段研究成果表示肯定,並期待第三階段的研究成果能夠更加豐富。中德兩國政府將會繼續支持中德電動汽車充電項目的持續推進。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

※回頭車貨運收費標準

分類
發燒車訊

年輕就要往前跑!2016奇瑞 “強音酷跑節”收官站引爆廣州

如今年輕的新生代正在成為車市主流消費群體,此次奇瑞與中國移動咪咕善跑的合作正是把握住了市場消費趨勢,率先在業內嘗試汽車與跑步領域的跨界,成功打造出汽車行業的跨界營銷典範。自今年10月15日以來,“強音酷跑節”相繼跑遍了合肥、蘇州、大連、青島、西安、成都、長沙等國內各大城市。

轉眼又到了周一,上周末廣州天氣好得不像話。天藍得像洗過一樣。就在12月3日,奇瑞汽車咪咕善跑“強音酷跑節”全國系列活動終極之戰—廣州站,震撼來襲!

為慶祝“強音酷跑節”完美收官,舞台上不僅彙集了星光熠熠的2016“中國新歌聲”新科冠軍蔣敦豪、2015“中國好聲音”總冠軍李琦和人氣歌手張瑋,還有專為冠軍打造的金色瑞虎7“冠軍版”在萬眾矚目中正式亮相,並由奇瑞官方贈予2016“中國新歌聲”冠軍蔣敦豪。這款全球唯一的特別定製版瑞虎7車身噴塗了閃耀的黃金車身顏色,內飾交織了金色縫線,彰顯出“冠軍版”的優雅與高貴,現場圈粉無數。此前, 瑞虎7曾作為2016浙江衛視“中國新歌聲”官方指定用車,見證蔣敦豪披荊斬棘、邁向冠軍的不凡之路,也正是在2016“中國新歌聲”冠軍誕生之夜,蔣敦豪對瑞虎7一見傾心。

奇瑞汽車華南大區總經理翟小兵為《中國新歌聲》冠軍蔣敦豪頒發榮譽車主證書

瑞虎7定位於“未來派超動感SUV”,是奇瑞戰略2.0時代為年輕消費群體量身打造的一款全新旗艦SUV。自9月20日上市以來,以澎湃的動力、超凡卓越的性能以及無與倫比的前瞻設計,樹立新一代中國品牌SUV的巔峰高度,更取得了首月訂單突破2萬的傲人成績。用戶口碑在汽車之家、易車等主流門戶網站高居同級榜首,成為時下年輕一族購買高品質SUV的首選。

2016《中國新歌聲》冠軍蔣敦豪

當冠軍遇上中國品牌的冠軍車型,兩個冠軍的光芒交相輝映。2016年,瑞虎7與“中國新歌聲”強強攜手,共同演繹“活耀不凡”的品牌精神,這也是中國汽車品牌第一次和現象級的原創綜藝節目合作,體現出瑞虎7的實力和視野。《中國新歌聲》作為今年夏天最受年輕人歡迎的綜藝節目,4.21的高收視率、超52億的網絡播放以及高互動社交聲量的頂級Ip號召力也是吸引瑞虎7冠名《中國新歌聲》的原因之一。兩者的目標受眾都是當今社會新生代年輕人,真實、勇氣、自信,用獨特魅力傳遞积極進取的正能量。值得一提的是,“活耀不凡”還是瑞虎7與“蔣敦豪們”的共同特徵:不甘平庸、執着追求、不斷挑戰自我的夢想激情。瑞虎7“冠軍版”正以一種獨特的精神致敬不凡,為時代唱響最美強音。

瑞虎7冠軍版亮相

強音酷跑,8城20萬公里跑遍全國

晚上19:00,在廣州海心沙亞運公園,由艾瑞澤5、瑞虎7一路閃耀領跑,在五彩的電光氛圍中,5000多名年輕人踩着勁爆的電音節拍,釋放內心的熱愛和激情,縱享奔跑之樂!5公里的熒光炫跑不僅有高顏值的美女跑團,還有動感熱辣的舞蹈嗨翻全場。由蔣敦豪、李琦及張瑋等歌手獻上活力四射的“好聲音”,讓現場秒變最熱狂歡派對。

李琦動感獻唱

當運動不止是運動,它的意義將變得更加深遠!作為各自領域的領頭羊,此次“強音酷跑節”由奇瑞汽車與中國移動咪咕善跑強強聯手,針對各自年輕目標用戶群體,融入汽車、跑步、音樂等生活潮流元素,堪稱珠聯璧合。如今年輕的新生代正在成為車市主流消費群體,此次奇瑞與中國移動咪咕善跑的合作正是把握住了市場消費趨勢,率先在業內嘗試汽車與跑步領域的跨界,成功打造出汽車行業的跨界營銷典範。

自今年10月15日以來,“強音酷跑節”相繼跑遍了合肥、蘇州、大連、青島、西安、成都、長沙等國內各大城市。所到之處,掀起了一陣陣青春風暴。歷時50天,8座城市,里程超過20萬公里,吸引了全國線上線下73萬參与人次,455家媒體報道,累計活動曝光更高達3.8億次,一系列令人欣喜的數據反映出此次營銷跨界的成功。

張瑋high歌引爆全場

通過“強音酷跑節”,奇瑞在85后、90后群體中的知名度和好感度逐步提升,也以實際行動帶動更多年輕人加入到跑步的行列,“青春領跑”理念深入人心。奇瑞汽車營銷公司副總經理范星表示:“希望通過強音酷跑節,把在音樂和跑步過程中體會到的正能量,傳遞給更多的城市年輕人,讓更多人在跑步中得到健康、快樂和友誼。同時也希望大家看到,奇瑞還很年輕,正在向著陽光努力奔跑,也期望年輕人與我們一道奔跑向前,勇敢追逐自己的夢想。”

營銷“年輕化” 奇瑞2.0向上突破

四年前,奇瑞開始了戰略2.0階段新一代產品的開發,致力於更滿足以追求品質生活的年輕消費群體的需求。2016年伊始,奇瑞以“Fun 精彩無限”為品牌核心底蘊,將品牌年輕化提升至企業戰略層面。

隨着年輕化戰略的推進與深化,以“年輕化”為切入點,奇瑞通過年輕人喜愛的娛樂化溝通平台及跨界營銷,建立起與年輕人溝通的橋樑。也讓更多年輕消費者近距離感受奇瑞2.0產品的品質,傳遞出奇瑞的品牌特質,進一步提升奇瑞品牌在年輕人群中的影響力。奇瑞“強音酷跑節”就是以音樂和運動為載體,抓住了年輕人最時尚的生活方式。艾瑞澤5、瑞虎7作為活動車型,讓更多年輕人看到奇瑞2.0產品的青春與動感,大大促進了產品銷量的提升。

廣州站的落幕為奇瑞“強音酷跑節”畫上了一個圓滿的句號,在一系列創新營銷的助推下,艾瑞澤5和瑞虎7領銜熱銷。上市以來,艾瑞澤5連續7個月銷量破萬,更以累計253天銷量突破十萬輛的成績刷新了中國品牌增速最快的新車記錄。而瑞虎7上市首月訂單即突破2萬輛,一度一車難求。相信通過一系列的強勢營銷和強大的產品力,奇瑞未來會有更突出的市場表現,推動奇瑞品牌的再次飛躍,引領中國品牌再向上。

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

【其他文章推薦】

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

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

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

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

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

網頁設計最專業,超強功能平台可客製化

※回頭車貨運收費標準

分類
發燒車訊

20-30多萬這個價格區間,可以買到最好的是什麼車?

0升自然吸氣發動機的動力水平。而5系入門車型的2。0T發動機型號為N20B20,沒錯就是寶馬那台著名的2。0T發動機了,寶馬的操控之王328i也用的N20B20,但是寶馬給520LI車型裝上的是一台低功率版本,最大功率僅僅184馬力,最大扭矩270牛米,這樣的動力水平只能說讓人失望。

如果你問我預算20-30萬注重生活品質與享受有什麼車型推薦,那麼我一定會推薦凱迪拉克XTS。

XTS定位於中大型轎車,和奧迪A6L/寶馬5系/奔馳E級同屬一個級別,但是XTS的定價卻是比這些車型足足低了近十萬,那麼定價低了這麼多的前提下,在品質上和這些車型相比如何呢?今天小編就拿寶馬5系的入門車型與凱迪拉克XTS的入門車型做個對比。

凱迪拉克XTS 2016款 28T 技術型

指導價:34.99萬(下文簡稱XTS)

寶馬5系 2017款 520Li 典雅型

指導價:43.56萬(下文簡稱5系)

凱迪拉克XTS足足比寶馬5系便宜了8.57萬。

外觀

XTS勻稱/5系運動化

XTS的外觀採用凱迪拉克獨特的鑽石切割設計,整車的線條十分有力,直線條的運用恰到好處,使得XTS顯得十分修長有氣派。XTS的長度為5131mm,比寶馬5系長了76mm,乘坐艙最大化的設計理念使得XTS的乘坐艙十分寬敞。而值得一提的是XTS的行李箱空間也達到了537升,這在中大型車中也是十分大的。

5系的外觀採用運動化設計,短前懸長車頭的造型十分有運動感,不過過長的車頭侵佔了不少的乘坐艙空間,使得5系雖然長度達到5055mm,但是車內乘坐空間差強人意。

內飾

5系用料差/XTS奢華

和外觀一樣,XTS的內飾設計上更多採用平直線條,使得整車更顯穩重與莊嚴,更加有豪華車的派頭,而在內飾用料上XTS也是不惜成本,XTS的內飾大量使用材質細膩的真皮包裹,而木紋材質、啞光鋁合金、鋼琴烤漆面板等十分顯檔次的材料的使用也烘託了車內的豪華氛圍,觸控面板/大尺寸液晶屏的使用也讓車內科技感十足。

寶馬5系的內飾設計造型使用老一代的寶馬家族風格,這也和這一代寶馬5系車型偏老有關,2010年面世的現款5系已經走過了6個年頭了,設計上已經有些跟不上時代了,而在用料上寶馬5系也是飽受詬病,大量硬塑料的使用使得車內檔次感十分差,基本上和20萬的中級車無異。

2.0T動力

XTS動力更強勁

兩款入門車型都用了2.0T的動力系統,2.0T也是現在的主流的動力系統,那麼兩款車的2.0T發動機有什麼差異呢?XTS的2.0T發動機型號為LTG,最大功率269馬力,最大扭矩400牛米,這已經相當於一台4.0升自然吸氣發動機的動力水平。

而5系入門車型的2.0T發動機型號為N20B20,沒錯就是寶馬那台著名的2.0T發動機了,寶馬的操控之王328i也用的N20B20,但是寶馬給520LI車型裝上的是一台低功率版本,最大功率僅僅184馬力,最大扭矩270牛米,這樣的動力水平只能說讓人失望。

音響

XTS標配BOSE音響

為什麼音響要單獨說呢?因為音響對於一台豪車是十分重要的,愜意的旅途中沒有好的音樂相伴,對不少豪車買家來說都是難熬的。凱迪拉克的運動性能成就聞名世界,但是另一個不為人知的就是凱迪拉克在音響方面的造詣,XTS的音響在汽車開發之初便傾力設計,能夠滿足對音樂最嚴苛的需求。XTS全系標配BOSE音響,音質無可挑剔,小編聽過之後都迷上了。

5系使用的普通的6喇叭音響,咳咳,就不多說了。

配置

XTS配置更加實用

在配置上兩車可以說是打成平手,雖然5系的配置更多,但是XTS的配置更加實用,全景天窗、膝部氣囊、R18輪轂、BOSE音響、定位互動服務等都更加的貼近用戶需要,而且考慮到他們之間8.57萬的差價,XTS顯然更加划算。

說了這麼多,20多萬也買不到XTS呀?

錯!凱迪拉克即將退出的XTS猴年限量版預售價26.99萬。雖然這款車型還未上市,但是據稱這款車型將保持凱迪拉克一如既往的高配置水平,5131*1852*1501mm的大尺寸,強勁的2.0T動力以及奢華的內飾,預售價26.99萬的XTS猴年限量版的競爭力在這個價位幾乎是無敵的存在。26.99萬買一款純正美系豪華中大型轎車,還有什麼好猶豫的呢?

XTS猴年限量版的推出降低了購買XTS的門檻,使得更多人可以加入到XTS大家庭來,可以和現有的熱愛生活、注重生活品質與生活質量、事業有成工作高效的XTS車主一起相處,共同體會生活的真諦。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

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

※回頭車貨運收費標準

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

分類
發燒車訊

這些配備了省油利器的自主SUV僅7萬起

99萬作為一款小型SUV,森雅R7擁有着圓潤飽滿的外觀,小巧時尚的設計很討人喜歡,前臉不規則的中網樣式搭配着造型別緻的大燈,增添了幾分硬朗的氣息。內飾的設計很有層次感,黑銀色搭配拉絲面板,給人很運動的感覺,9英寸的中控大屏是一大亮點,包含了手機互聯和導航等功能,自動防炫目后視鏡出現在尊貴型車型上,檔次感瞬間提升了不少。

隨着科技的發展越來越迅速,汽車技術也在不斷的進步,自動變速箱的出現解決了我們黃金左腳的命運,使駕駛者在擁堵的城市中輕鬆地駕駛車輛,那麼隨着燃油價格的不斷提升,人們有沒有想出比較省油的汽車技術呢?

答案是肯定的,那就是發動機自動啟停系統,在車輛臨時停車等紅燈的時候,會自動熄火,待汽車需要重新啟動時,又能快速啟動發動機,大大的減小了油耗和廢氣的排放,綜合下來此項技術可以節約車子一年5%-15%的燃油哦,來看一下哪些自主品牌SUV都有配備這項技術的吧!

奇瑞汽車-瑞虎7

指導價:9.79-15.39萬

說瑞虎7是奇瑞目前最好的SUV一點也不為過,時尚精緻的外觀,凌厲的腰線和車身比例非常的協調,三叉戟式的大燈和造型獨特的進氣格柵使其看上去辨識度很高。

內飾無論是做工還是用料都給人留下深刻的印象,大量帶縫線的皮質材料和軟質搪塑工藝材料,豪華感十足,簡潔的中控大屏、自動頭燈(LED光源)、座椅加熱、無鑰匙進入/啟動等配置十分齊全。

2650mm的軸距雖在同級別對手中並不佔優,但是實際的乘坐感受還是表現很出色的,座椅的包裹性好,肩部支撐很到位,動力方面提供1.5T+6擋手動/雙離合變速器,或者2.0L+CVT變速箱的組合,懸架方面則採用了常規的前麥弗遜后多連桿式獨立懸架。

一汽吉林-森雅R7

指導價:6.89-9.99萬

作為一款小型SUV,森雅R7擁有着圓潤飽滿的外觀,小巧時尚的設計很討人喜歡,前臉不規則的中網樣式搭配着造型別緻的大燈,增添了幾分硬朗的氣息。

內飾的設計很有層次感,黑銀色搭配拉絲面板,給人很運動的感覺,9英寸的中控大屏是一大亮點,包含了手機互聯和導航等功能,自動防炫目后視鏡出現在尊貴型車型上,檔次感瞬間提升了不少。

森雅R7的軸距為2600mm,在這個價位車型中比較有優勢,無論是前後排的頭部空間還是腿部空間都相當寬敞;動力方面全系搭載1.6L自然吸氣發動機,最大功率116馬力,匹配5擋手動或者6擋手自一體變速器,全系標配發動機啟停功能,油耗表現更出色。

長安汽車-長安CS15

指導價:5.79-7.79萬

長安CS15的外觀充滿了個性化的設計元素,稜角分明的造型和豐富的線條相互搭配,看上去顯得更為硬朗,中網的造型也是獨樹一幟,側面較高的腰線設計,使得其車門肌肉感十足,整車是偏向運動的設計路線。

內飾為飛翼式的家族設計風格,紅色縫線的三幅式方向盤、炮筒式的儀錶盤有着濃厚的運動味道,製作工藝堪比合資車,胎壓監測、無鑰匙進入/啟動、上坡輔助、倒車影像等配置一應俱全。

雖然CS15是一款小型SUV,軸距也只有2510mm,但是內部空間完全超出你的想象,乘坐感受相當舒適,大大小小的儲物格達到39處之多,便利性很強,全系採用1.5L+5擋手動/5擋雙離合的動力組合,8萬塊買自動擋性價比是相當高的。

總結:瑞虎7的價格相對來說有些高,但畢竟是跨級別的,做工水平整體很高,堪比合資車,森雅R7的表現中規中矩,全系標配發動機啟停非常厚道,長安CS15的性價比最高,麻雀雖小五臟俱全,適合年輕人的第一台車。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※回頭車貨運收費標準

台中搬家公司費用怎麼算?

分類
發燒車訊

【Spring註解驅動開發】自定義TypeFilter指定@ComponentScan註解的過濾規則

寫在前面

Spring的強大之處不僅僅是提供了IOC容器,能夠通過過濾規則指定排除和只包含哪些組件,它還能夠通過自定義TypeFilter來指定過濾規則。如果Spring內置的過濾規則不能夠滿足我們的需求,那麼我們就可以通過自定義TypeFilter來實現我們自己的過濾規則。

項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

FilterType中常用的規則

在使用@ComponentScan註解實現包掃描時,我們可以使用@Filter指定過濾規則,在@Filter中,通過type指定過濾的類型。而@Filter註解的type屬性是一個FilterType枚舉,如下所示。

package org.springframework.context.annotation;

public enum FilterType {
	ANNOTATION,
	ASSIGNABLE_TYPE,
	ASPECTJ,
	REGEX,
	CUSTOM
}

每個枚舉值的含義如下所示。

(1)ANNOTATION:按照註解進行過濾。

例如,使用@ComponentScan註解進行包掃描時,按照註解只包含標註了@Controller註解的組件,如下所示。

@ComponentScan(value = "io.mykit.spring", includeFilters = {
    @Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
}, useDefaultFilters = false)

(2)ASSIGNABLE_TYPE:按照給定的類型進行過濾。

例如,使用@ComponentScan註解進行包掃描時,按照給定的類型只包含PersonService類(接口)或其子類(實現類或子接口)的組件,如下所示。

@ComponentScan(value = "io.mykit.spring", includeFilters = {
    @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonService.class})
}, useDefaultFilters = false)

此時,只要是PersonService類型的組件,都會被加載到容器中。也就是說:當PersonService是一個Java類時,Person類及其子類都會被加載到Spring容器中;當PersonService是一個接口時,其子接口或實現類都會被加載到Spring容器中。

(3)ASPECTJ:按照ASPECTJ表達式進行過濾

例如,使用@ComponentScan註解進行包掃描時,按照ASPECTJ表達式進行過濾,如下所示。

@ComponentScan(value = "io.mykit.spring", includeFilters = {
    @Filter(type = FilterType.ASPECTJ, classes = {AspectJTypeFilter.class})
}, useDefaultFilters = false)

(4)REGEX:按照正則表達式進行過濾

例如,使用@ComponentScan註解進行包掃描時,按照正則表達式進行過濾,如下所示。

@ComponentScan(value = "io.mykit.spring", includeFilters = {
    @Filter(type = FilterType.REGEX, classes = {RegexPatternTypeFilter.class})
}, useDefaultFilters = false)

(5)CUSTOM:按照自定義規則進行過濾。

如果實現自定義規則進行過濾時,自定義規則的類必須是org.springframework.core.type.filter.TypeFilter接口的實現類。

例如,按照自定義規則進行過濾,首先,我們需要創建一個org.springframework.core.type.filter.TypeFilter接口的實現類MyTypeFilter,如下所示。

public class MyTypeFilter implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        return false;
    }
}

當我們實現TypeFilter接口時,需要實現TypeFilter接口中的match()方法,match()方法的返回值為boolean類型。當返回true時,表示符合規則,會包含在Spring容器中;當返回false時,表示不符合規則,不會包含在Spring容器中。另外,在match()方法中存在兩個參數,分別為MetadataReader類型的參數和MetadataReaderFactory類型的參數,含義分別如下所示。

  • metadataReader:讀取到的當前正在掃描的類的信息。
  • metadataReaderFactory:可以獲取到其他任務類的信息。

接下來,使用@ComponentScan註解進行如下配置。

@ComponentScan(value = "io.mykit.spring", includeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
}, useDefaultFilters = false)

在FilterType枚舉中,ANNOTATION和ASSIGNABLE_TYPE是比較常用的,ASPECTJ和REGEX不太常用,如果FilterType枚舉中的類型無法滿足我們的需求時,我們也可以通過實現org.springframework.core.type.filter.TypeFilter接口來自定義過濾規則,此時,將@Filter中的type屬性設置為FilterType.CUSTOM,classes屬性設置為自定義規則的類對應的Class對象。

實現自定義過濾規則

在項目的io.mykit.spring.plugins.register.filter包下新建MyTypeFilter,並實現org.springframework.core.type.filter.TypeFilter接口。此時,我們先在MyTypeFilter類中打印出當前正在掃描的類名,如下所示。

package io.mykit.spring.plugins.register.filter;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

/**
 * @author binghe
 * @version 1.0.0
 * @description 自定義過濾規則
 */
public class MyTypeFilter implements TypeFilter {
    /**
     * metadataReader:讀取到的當前正在掃描的類的信息
     * metadataReaderFactory:可以獲取到其他任務類的信息
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //獲取當前類註解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //獲取當前正在掃描的類的信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //獲取當前類的資源信息,例如:類的路徑等信息
        Resource resource = metadataReader.getResource();
        //獲取當前正在掃描的類名
        String className = classMetadata.getClassName();
        //打印當前正在掃描的類名
        System.out.println("-----> " + className);
        return false;
    }
}

接下來,我們在PersonConfig類中配置自定義過濾規則,如下所示。

@Configuration
@ComponentScans(value = {
        @ComponentScan(value = "io.mykit.spring", includeFilters = {
                @Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
        }, useDefaultFilters = false)
})
public class PersonConfig {

    @Bean("person")
    public Person person01(){
        return new Person("binghe001", 18);
    }
}

接下來,我們運行SpringBeanTest類中的testComponentScanByAnnotation()方法進行測試,輸出的結果信息如下所示。

-----> io.mykit.spring.test.SpringBeanTest
-----> io.mykit.spring.bean.Person
-----> io.mykit.spring.plugins.register.controller.PersonController
-----> io.mykit.spring.plugins.register.dao.PersonDao
-----> io.mykit.spring.plugins.register.filter.MyTypeFilter
-----> io.mykit.spring.plugins.register.service.PersonService
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
personConfig
person

可以看到,已經輸出了當前正在掃描的類的名稱,同時,除了Spring內置的bean名稱外,只輸出了personConfig和person,沒有輸出使用@Repository、@Service、@Controller註解標註的組件名稱。這是因為當前PersonConfig上標註的@ComponentScan註解是使用自定義的規則,而在MyTypeFilter自定義規則的實現類中,直接返回了false值,將所有的bean都排除了。

我們可以在MyTypeFilter類中簡單的實現一個規則,例如,當前掃描的類名稱中包含有字符串Person,就返回true,否則返回false。此時,MyTypeFilter類中match()方法的實現如下所示。

    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //獲取當前類註解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //獲取當前正在掃描的類的信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //獲取當前類的資源信息,例如:類的路徑等信息
        Resource resource = metadataReader.getResource();
        //獲取當前正在掃描的類名
        String className = classMetadata.getClassName();
        //打印當前正在掃描的類名
        System.out.println("-----> " + className);
        return className.contains("Person");
    }

此時,在io.mykit.spring包下的所有類都會通過MyTypeFilter類的match()方法,來驗證類名是否包含Person,如果包含則返回true,否則返回false。

我們再次運行SpringBeanTest類中的testComponentScanByAnnotation()方法進行測試,輸出的結果信息如下所示。

-----> io.mykit.spring.test.SpringBeanTest
-----> io.mykit.spring.bean.Person
-----> io.mykit.spring.plugins.register.controller.PersonController
-----> io.mykit.spring.plugins.register.dao.PersonDao
-----> io.mykit.spring.plugins.register.filter.MyTypeFilter
-----> io.mykit.spring.plugins.register.service.PersonService
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
personConfig
person
personController
personDao
personService

此時,結果信息中輸出了使用@Repository、@Service、@Controller註解標註的組件名稱,分別為:personDao、personService和personController。

好了,咱們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!!

項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

寫在最後

如果覺得文章對你有點幫助,請微信搜索並關注「 冰河技術 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回復“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再迷茫。

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

【其他文章推薦】

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

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

※超省錢租車方案

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

網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

分類
發燒車訊

mybatis 逆向工程使用姿勢不對,把表清空了,心裏慌的一比,於是寫了個插件。

使用mybatis逆向工程的時候,delete方法的使用姿勢不對,導致表被清空了,在生產上一刷新后發現表裡沒數據了,一股涼意從腳板心直衝天靈蓋。

於是開發了一個攔截器,並寫下這篇文章記錄並分享。

這鍋只能自己背了

你用過 mybatis 逆向工程(mybatis-generator-maven-plugin)生成相關文件嗎?

就像這樣式兒的:

可以看到逆向工程幫我們生成了實體類、Mapper 接口和 Mapper.xml。

用起來真的很方便,我用了好幾年了,但是前段時間翻車了。

具體是怎麼回事呢,我給大家擺一下。

先說一下需求吧。就是在做一次借據數據遷移的過程中,要先通過 A 服務的接口拿到所有的借據和對應的還款計劃數據,然後再對這些借據進行核查,如果不滿足某些添加,就需要從表中刪除借據和對應的還款計劃。

借據和對應的還款計劃存放在兩張表中,用借據號來關聯。

而上線之後,我在一片歡聲笑語中把還款計劃表清空了,而這個必現的問題,在測試階段同學還沒有測試出來。

事情發生后我趕緊找到了 DBA 協助修複數據:

是怎麼回事呢,為了模擬這個場景,我在本地創建了兩張表,訂單表(orderInfo)和訂單擴展表(orderInfoExt),他們之間用訂單號進行關聯:

僅僅是做演示,所以兩張表是非常簡單的,

我們假設現在表裡面的這條訂單號為 2020060666666 的數據經過判斷是錯誤數據,我當時寫的代碼體現在單元測試裏面是這樣的:

看出問題了嗎?

第 42 行用的 example 對象還是 OrderInfo 的 example。而真正的 OrderInfoExt 對象的 exampleExt 對象沒有進行任何賦值的操作。

為什麼會出現這樣的烏龍呢?

都怪 idea 太智能了!(強行找個借口)

我只需要打一個 ex 然後回個車…. example 就出現在代碼裏面了。

而這種沒有參數的 example 傳進去,在 mapper.xml 裏面是這樣處理的:

執行一下,看看效果:

看到 delete from order_info_ext 語句。你說你慌不慌?

當然在線上的服務器肯定是看不到執行的 SQL 的,但是當報警短信一條一條接着來的時候,當連上數據庫一看錶,發現數據沒了的時候。

你說你慌不慌?

反正我一刷新后發現表裡沒數據了,一股涼意從腳板心直衝天靈蓋。這種時候都還是要小小的心慌一下,先大喊一聲“卧槽!數據怎麼沒了?”

然後趕緊報備,準備找 DBA 撈數據吧。

還好,本次誤刪不影響正常業務。

數據恢復過程就不說了,聊一下這事發生后我的一點思考吧。

哦,對了,還得說一下測試同學為什麼沒有發現這個問題。這個問題確實是一個必現的問題,測試案例上也寫了這個測試點。

但是測試同學查看數據的時候用的是 select 語句,查詢條件給的是確實需要被刪除的數據 。

然後分別在兩個表裡面執行后發現:數據確實是沒了。

是的,是數據確實是沒了。整個表都乾淨了。

看着測試妹子驚慌失措的樣子,我還能怎麼說呢?

這鍋,不甩了,我自己背下來吧。

重新審視逆向工程

我們先看看逆向工程幫我們生成的接口:

我相信用過 mybatis 逆向工程的朋友們,一看到這幾個接口就知道了:喲,這都是老朋友了。

當我再去重新審視這些接口的時候我會發現其實還有會有一些問題的。

比如 delete 這樣的高危語句我們還是需要盡量的手寫 xml。

比如 updateByExample 同樣存在由於誤操作沒有 where 條件,導致全表更新的情況。

比如 select 語句是查出了整個對象,但是有時間我們可能只需要對象裏面的某個值而已。

比如 select 語句針對大表、關鍵表操作的時候,不能從代碼的角度限定 SQL 必須帶上索引字段查詢。

上面的這些問題我們怎麼處理呢?

我的建議是不要使用 mybatis 的逆向工程,全都手寫。

開個玩笑。我們肯定不能因噎廢食,何況逆向工程確實是幫我們做了很多工作,極大的方便我們這樣的 CRUD Boy 進行 CRUD。

所以,我想 mybatis 的逆向工程肯定是有什麼配置來控制生成哪些接口的,別問為什麼,問就是直覺。

因為要是讓我去開發這樣的一個插件,我肯定也會提供對應的開關配置。

我現在的想法是不讓它給我生成 delete 相關的接口,這個接口用起來我心裏害怕。

所以怎麼配置呢?

我們去它的 DTD 文件裏面找一下嘛:

這個文件不長,一共也才 213 行,你能發現這一塊東西:

你用腳指頭想也能知道,這就是我們要找的開關配置。從 DTD 文件的描述中來看,這個幾個參數是配置在 table 標籤裏面的。

我們去試一下:

果然是這樣的。然後我們進行相關配置如下:

再生成一下:

果然,delete 相關的接口沒了。

然後我們程序中真的需要 delete 操作的時候,再自己去手寫 xml 文件。

那你自己寫的 xml 文件也忘記寫 where 條件了這麼辦?

這個月工資別領了。自己好好反思反思。

當然,就算你真的忘記寫了,下面這個攔截器還能給你兜個底,幫你一把。

mybatis 攔截器使用

其實這個方案是我想到的第一個方案。導致上面問題的原因很簡單嘛,就是執行了delete 語句卻沒有 where 條件。

那麼我們可以攔截到這個 SQL 語句,然後對其進行兩個判斷:

是否是 delete 語句。 如果是,是否包含 where 條件。

那麼問題來了,我們怎麼去攔截到這個 SQL 呢?

答案就是我們可以開發一個 mybatis 插件呀,就像分頁插件那樣。

插件,聽起來很高端的樣子,其實他就是個攔截器。實現起來非常簡單。

先去官網上看一下:

中文:https://mybatis.org/mybatis-3/zh/configuration.html#plugins

英文:https://mybatis.org/mybatis-3/configuration.html

在官網上,對於插件這一模塊的描述是這樣的:

通過 MyBatis 提供的強大機制,使用插件是非常簡單的,只需實現 Interceptor 接口,並指定想要攔截的方法簽名即可。

正如官網說的這樣,插件開發、使用起來是非常簡單的。只需要三步:

1.實現 Interceptor 接口。

2.指定想要攔截的方法簽名。

3.配置這個插件。

mybatis 插件開發

基於上面這三步,大家先看一下我們這插件怎麼寫,以及這個插件的效果。

先說明一下本文涉及到的源碼 mybatis 版本是 3.4.0。

本文用攔截器的目的是判斷 delete 語句中是否有 where 條件。所以,開發出來的插件長這樣:

再來一個複製粘貼直接運行版本:

@Slf4j
@Intercepts({
        @Signature(type = Executor.class, method = "update",
                args = {MappedStatement.class, Object.class}),
})
public class CheckSQLInterceptor implements Interceptor {

    private static String SQL_WHERE = "where";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //獲取方法的第0個參數,也就是MappedStatement。@Signature註解中的args中的順序
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        //獲取sql命令操作類型
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        final Object[] queryArgs = invocation.getArgs();
        final Object parameter = queryArgs[1];
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        String sql = boundSql.getSql();
        if (SqlCommandType.DELETE.equals(sqlCommandType)) {
            //格式化sql
            sql = sql.replace("\n", "");
            if (!sql.toLowerCase().contains(SQL_WHERE)) {
                sql = sql.replace(" ", "");
                log.info("刪除語句中沒有where條件,sql為:{}", sql);
                throw new Exception("刪除語句中沒有where條件");
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}

再把插件註冊上(註冊插件還有其他的方法,後面會講到,這裏只是展示Bean注入的方式):

我們先看看配上插件后的執行效果:

可以看到日誌中輸出了:

刪除語句中沒有where條件,sql為:delete from order_info_ext

並拋出了異常。

這樣,我們的擴展表的數據就保住了。在測試階段,測試同學就一定能扯出來問題,瞟一眼日誌就明白了。

就算測試同學忘記測試了,在生產上也不會執行成功,拋出異常后還會有報警短信通知到相應的開發負責人,及時登上服務器去處理。

功能實現了,確實是非常的簡單。

我們再說回代碼,你說說看:當你拿到上面這段代碼后,最迷惑的地方是哪裡?

其中的邏輯是很簡單的了。 沒有什麼特別的地方,我想大多數人拿到這段代碼迷惑的地方在於這個地方吧:

這個 @Intercepts 裏面的 @Signature 裏面為什麼要這樣配置?

我們先看看 @Intercepts 註解:

裏面是個數組,可以配置多個 Signature。所以,其實這樣配置也是可以的:

關鍵的地方在於 @Signature 怎麼配置:

這個問題,我們放到下一節去討論。

mybatis插件的原理

上面一小節我們知道了對於開發插件而言,難點在於 @Signature 怎麼配置。

其實這也不能叫難點,只能說你不知道能配置什麼,比較茫然而已。這一小節就來回答這個問題。

要知道怎麼配置就必須要了解mybatis 這四大對象:Executor、ParameterHandler 、ResultSetHandler 、StatementHandler 。

官網上說:

MyBatis 允許你在映射語句執行過程中的某一點進行攔截調用。默認情況下,MyBatis 允許使用插件來攔截的方法調用包括:

Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)

ParameterHandler (getParameterObject, setParameters)

ResultSetHandler (handleResultSets, handleOutputParameters)

StatementHandler (prepare, parameterize, batch, update, query)

那官網上說的這四大對象分別是拿來幹啥用的呢?

Executor:Mybatis 的執行器,用於進行增刪改查的操作。

ParameterHandler :參數處理器,用於處理 SQL 語句中的參數對象。

ResultSetHandler:結果處理器,用於處理 SQL 語句的返回結果。

StatementHandler :數據庫的處理對象,用於執行SQL語句

知道攔截的四大對象了,我們就可以先揭秘一下上面的這個註解配置的是啥了:

type 字段存放的是 class 對象,其取值範圍就是上面說的四大對象。

method 字段存放的是 class 對象的具體方法。

args 存放的是具體方法的參數。

看到這幾個參數你想到了什麼?有沒有條件反射式的想到反射?如果沒有的話你再咂摸咂摸,看看能不能品出一點反射的味道。

本文用攔截器的目的是判斷 delete 語句中是否有 where 條件,因此經過上面的分析,Executor 對象就能滿足我們的需求。

所以在本文示例中 @Signature 的 type 字段就是 Executor.class。

那 method 字段我們放哪個方法呢?放 delete 嗎?

這就得看看 Executor 對象的方法有哪些:

可以看到其中並沒有 delete 方法,和 SQL 執行相關的,看起來只有 query和 update。

但是,我們可以大膽猜測一下呀:delete 也是一種 update。

接着去求證一下就行:

可以看到 delete 方法確實是調用了 update 方法。

所以在本文案例中 @Signature 的 method 字段放的是 update 方法。

已經知道具體的方法了,那 args 放的就是方法的入參,所以這段配置就是這樣來的:

真的,我覺得這屬於手摸手教學系列了。經過這個簡單的案例,我希望大家能做到一通百通。

接下來帶大家看看我們常用的分頁插件 pageHelper 是怎麼做的吧。

其實你用腳指頭也能想到,分頁插件肯定是攔截的查詢方法,我們只是需要去驗證一下就可以。

引入 pageHelper 后可以看到 Interceptor 的多了兩個實現:

我們看一下 PageInterceptor 方法吧:

對吧,攔截了兩個 query 方法,一個參數是 4 個,一個參數是 6 個:

同時,在 intercept 的實現裏面有一部分是這樣寫的:

4 個參數和 6 個參數是做了單獨處理的,至於為什麼要這樣處理,至於為什麼要攔截兩個 query 方法,說起來又是一個很長的故事了。

詳細的可以看看這個鏈接: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Interceptor.md

好了,還是那句話:如果要寫出好的 mybatis 插件,必須知道 @Signature 怎麼去配置。配置后能攔截哪些東西,你心裏應該是有點數的。

mybatis插件的原理

前面我們知道攔截器怎麼寫了,接下來簡單的分析一波原理。

前幾天我看到一個觀點是說看開源框架的源碼建議從 mybatis 看起。我是很贊成這個觀點的,確實是優雅,而容易看懂。能品出很多設計模式的使用。

一句話總結 mybatis插件的原理就是:動態代理加上責任鏈。

先看一下 Plugin 類的動態代理:

標號為 ① 的地方一看就知道,InvocationHandler,JDK 動態代理,沒啥說的。

標號為 ② 的地方是 wrap 方法,生成 Plugin 代理對象。

標號為 ③ 的地方是 invoker 方法,圈起來的目的是想說是在這裏判斷當前方法是否是需要被攔截的方法。如果是則用代理對象走攔截器邏輯,如果不是則用目標對象,走正常邏輯。

給大家看一下這個地方的 debug 效果:

一個平平無奇的 if 判斷,是攔截器的關鍵。為什麼這個地方多說了幾句呢?

因為其實這就是細節的地方。當面試的時候面試官問你:mybatis 是怎麼判斷是否需要攔截這個方法的時候你能答上來。說明你是真的看過源碼。

責任鏈是怎麼體現的呢?

就是這個地方: org.apache.ibatis.plugin.InterceptorChain

你看又學到一招,mybatis 裏面的設計模式還有責任鏈。

我們看一下 pluginAll 方法的調用方:

這個地方就體現出之前官網說的了:

插件是作用於這四大對象的:Executor、ParameterHandler 、ResultSetHandler 、StatementHandler 。

上面框起來的這四個框,就是插件調用的地方。

那麼插件在什麼時候被加載,或者說什麼是被註冊上的呢?

還是回到攔截鏈這個類上去:

pluginAll 方法我們已經知道有哪些地方調用了。這個方法裏面其實還有兩個考點。

第一就是 interceptor 這個 List 集合的定義,用了 final 修飾。所以要注意 final 修飾基本類型和引用類型的區別,被 final 修飾的引用類型變量內部的內容是可以發生變化的。

第二就是 getInterceptors 返回的是一個不可修改的 List 。所以,要對集合 interceptors 進行修改,只能通過 addInterceptor 方法進行元素添加,保證了這個集合是可控的。

所以,我們只需要知道哪裡調用了 addInterceptor 方法,哪裡就是插件被註冊的地方。

一個是 SqlSessionFactoryBean ,一個是 XMLConfigBuilder。

使用 XML 配置是這樣的:

熟悉 mybatis 的朋友們肯定知道,無非就是對於標籤的解析而已。

解析到 plugins 標籤,則進入 pluginElement 方法中,在這個方法裏面調用 addInterceptor:

本文沒有使用 XML 的形式配置,所以我們主要看一下 SqlSessionFactoryBean。

怎麼看呢?

不要盲目的走入源碼,加個斷點看調用鏈,跟着調用鏈去走就很清晰了。

在這個地方加一個斷點:

然後 debug 起來,你就可以看到整個調用鏈了:

然後我們根據上面的調用鏈,我們就可以找到源頭了:

在 MybatisAutoConfiguration 的構造方法裏面初始化了 interceptors。

而 interceptorsProvider.getIfAvailable() 方法也解釋了為什麼我們只需要在程序裏面這樣注入我們的攔截器就可以被找到了:

對 getIfAvailable 方法不熟悉的朋友可以去補一下這塊的知識,我這裏只是給大家看一下這個方法上的註釋:

當然,你這樣去注入的話有可能會不生效,你就會大罵一聲:寫的什麼垃圾玩意,配置上了也不對呀。

別著急呀,我還沒說完呢。你看看是不是有自定義的 SqlSessionFactory 在項目里。

看一下注入 SqlSessionFactory 的源碼上面的那個註解了嗎?

@ConditionalOnMissingBean ,看名字也知道了,當你的項目裏面沒有自定義的 SqlSessionFactory 的時候,才會由源碼給你注入,這個時候才會正在的註冊上插件:

如果你有自定義的 SqlSessionFactory,那麼請手動調用 factory.setPlugins 方法。

所以,總結一下插件的三種配置方法:

1.xml方式配置。

2.如果沒有自定義 SqlSessionFactory 直接 @Bean 注入攔截器即可。

3.如果有自定義 SqlSessionFactory 需要在自定義的地方手動調用 factory.setPlugins 方法。

其實我嘗試過第四種方法,在application.properties 裏面配置:

這種配置方式才是符合 SpringBoot 思想的配置。才是真正的絲滑,潤物無聲的絲滑。

可惜,我配置上后,點擊到對應的源碼地方一看:

它調用的是 getInterceptors 方法,我就知道肯定是有問題了:

果然,運行起來會報這樣的錯誤: Failed to bind properties under 'mybatis.configuration.interceptors' to java.util.List<org.apache.ibatis.plugin.Interceptor>

找了一圈原因,最後發現了這個 issue:

github.com/mybatis/spring-boot-starter/issues/180

這個“奇異博士”頭像的用戶提出了和我一樣的問題:

然後下面的回答是這樣的:

別問,問就是不支持。請使用 @Bean 的方式。

最後說一句(求關注)

點個“贊”吧,周更很累的,不要白嫖我,需要一點正反饋。

才疏學淺,難免會有紕漏,如果你發現了錯誤的地方,還請你指出來,我對其加以修改。

感謝您的閱讀,我堅持原創,十分歡迎並感謝您的關注。

我是 why,一個被代碼耽誤的文學創作者,不是大佬,但是喜歡分享,是一個又暖又有料的四川好男人。

歡迎關注我的微信公眾號:why技術。在這裏我會分享一些java技術相關的知識,用匠心敲代碼,對每一行代碼負責。偶爾也會荒腔走板的聊一聊生活,寫一寫書評、影評。感謝你的關注,願你我共同進步。

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

網頁設計最專業,超強功能平台可客製化

分類
發燒車訊

ASP.NET Core中間件與HttpModule有何不同

前言

在ASP.NET Core中最大的更改之一是對Http請求管道的更改,在ASP.NET中我們了解HttpHandlerHttpModule但是到現在這些已經被替換為中間件那麼下面我們來看一下他們的不同處。

HttpHandler

Handlers處理基於擴展的特定請求,HttpHandlers作為進行運行,同時做到對ASP.NET響應請求。他是一個實現System.Web.IHttphandler接口的類。任何實現IHttpHandler接口的類都可以作為Http請求處理響應的目標程序。
它提供了對文件特定的擴展名處理傳入請求,
ASP.NET框架提供了一些默認的Http處理程序,最常見的處理程序是處理.aspx文件。下面提供了一些默認的處理程序。

Handler Extension Description
Page Handler .aspx handle normal WebPages
User Control Handler .ascx handle Web user control pages
Web Service Handler .asmx handle Web service pages
Trace Handler trace.axd handle trace functionality

創建一個自定義HttpHandler


public class CustomHttpHandler:IHttpHandler
{
    
    public bool IsReusable
    {
        //指定是否可以重用處理程序
        get {return true;}
    }
    
    public void ProcessRequest(HttpContext context)
    {
        //TODO
        throw new NotImplementedException();
    }
}

在web.config中添加配置項

<!--IIS6或者IIS7經典模式-->  
  <system.web>  
    <httpHandlers>  
      <add name="mycustomhandler" path="*.aspx" verb="*" type="CustomHttpHandler"/>  
    </httpHandlers>  
  </system.web>  
   
<!--IIS7集成模式-->  
  <system.webServer>  
    <handlers>  
       <add name="mycustomhandler" path="*.aspx" verb="*" type="CustomHttpHandler"/>  
    </handlers>  
  </system.webServer>  

異步HttpHandlers

異步的話需要繼承HttpTaskAsyncHandler類,HttpTaskAsyncHandler類實現了IHttpTaskAsyncHandlerIHttpHandler接口

public class CustomHttpHandlerAsync:HttpTaskAsyncHandler
{
    
    public override Task ProcessRequestAsync(HttpContext context)
    {

        throw new NotImplementedException();
    }
}

HttpModule

下面是來自MSDN

Modules are called before and after the handler executes. Modules enable developers to intercept, participate in, or modify each individual request. Modules implement the IHttpModule interface, which is located in the System.Web namespace.

HttpModule類似過濾器,它是一個基於事件的,在應用程序發起到結束的整個生命周期中訪問事件

自定義一個HttpModule

public class CustomModule : IHttpModule
    {
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(BeginRequest);
            context.EndRequest += new EventHandler(EndRequest);
        }
        void BeginRequest(object sender, EventArgs e)
        {
            ((HttpApplication)sender).Context.Response.Write("請求處理前");
        }

        void EndRequest(object sender, EventArgs e)
        {
            ((HttpApplication)sender).Context.Response.Write("請求處理結束后");
        }
    }


web.config中配置

<!--IIS6或者IIS7經典模式-->  
<system.web>  
    <httpModules>  
      <add name="mycustommodule" type="CustomModule"/>  
    </httpModules>  
  </system.web>  
<!--IIS7集成模式-->  
<system.webServer>  
    <modules>  
      <add name="mycustommodule" type="CustomModule"/>  
    </modules>  
</system.webServer>  

中間件

中間件可以視為集成到Http請求管道中的小型應用程序組件,它是ASP.NET中HttpModule和HttpHandler的結合,它可以處理身份驗證、日誌請求記錄等。

中間件和HttpModule的相似處

中間件和HttpMoudle都是可以處理每個請求,同時可以配置進行返回我們自己的定義。

中間件和httpModule之間的區別

HttpModule 中間件
通過web.config或global.asax配置 在Startup文件中添加中間件
執行順序無法控制,因為模塊順序主要是基於應用程序生命周期事件 可以控制執行內容和執行順序按照添加順序執行。
請求和響應執行順序保持不變 響應中間件順序與請求順序相反
HttpModules可以附件特定應用程序事件的代碼 中間件獨立於這些事件

中間件示例

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
      if (env.IsDevelopment())
      {
          app.UseDeveloperExceptionPage();
      }

      app.UseHttpsRedirection();

      app.UseRouting();

      app.UseAuthorization();

      app.UseEndpoints(endpoints =>
      {
          endpoints.MapControllers();
      });
  }

在如上代碼片段中我們有一些中間件的添加,同時也有中間件的順序。

Reference

How ASP.NET Core 1.0 Middleware is different from HttpModule

https://support.microsoft.com/en-us/help/307985/info-asp-net-http-modules-and-http-handlers-overview

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

【其他文章推薦】

網頁設計最專業,超強功能平台可客製化

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家公司費用怎麼算?

分類
發燒車訊

詳解SpringBoot(2.3)應用製作Docker鏡像(官方方案)

關於《SpringBoot-2.3容器化技術》系列

《SpringBoot-2.3容器化技術》系列,旨在和大家一起學習實踐2.3版本帶來的最新容器化技術,讓咱們的Java應用更加適應容器化環境,在雲計算時代依舊緊跟主流,保持競爭力;

全系列文章分為主題和輔助兩部分,主題部分如下:

  1. 《體驗SpringBoot(2.3)應用製作Docker鏡像(官方方案)》;
  2. 《詳解SpringBoot(2.3)應用製作Docker鏡像(官方方案)》;
  3. 《掌握SpringBoot-2.3的容器探針:基礎篇》;
  4. 《掌握SpringBoot-2.3的容器探針:深入篇》;
  5. 《掌握SpringBoot-2.3的容器探針:實戰篇》;

輔助部分是一些參考資料和備忘總結,如下:

  1. 《SpringBoot-2.3鏡像方案為什麼要做多個layer》;
  2. 《設置非root賬號不用sudo直接執行docker命令》;
  3. 《開發階段,將SpringBoot應用快速部署到K8S》;

本篇簡介

在前文,咱們快速體驗了官方推薦的docker鏡像製作方案,但也產生了幾個疑問:

  1. SpringBoot-2.3版本推薦的鏡像構建方案和舊版本比有什麼不同?
  2. pom.xml中spring-boot-maven-plugin插件新增的參數,到底做了什麼?
  3. Dockerfile中,java -Djarmode=layertools -jar application.jar extract這個操作啥意思?

本篇的目標就是解答上述問題,在尋找答案的過程中不斷補全知識點,提升自己;

關鍵知識點:鏡像layer

前文多次提到的鏡像layer到底是什麼,為什麼會有多層layer?有必要先把這個知識點夯實了,請參考文章《SpringBoot-2.3鏡像方案為什麼要做多個layer》

老版本SpringBoot的官方方案

SpringBoot-2.2.0.RELEASE版本為例,官方文檔(
https://docs.spring.io/spring-boot/docs/2.2.0.RELEASE/reference/pdf/spring-boot-reference.pdf)給出的做法如下:

  1. 將SpringBoot工程編譯構建,在target目錄得到jar;
  2. 在target目錄新建dependency文件夾;
  3. 將jar解壓到dependency文件夾;
  4. 編寫Dockerfile文件,內容如下:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.MyApplication"]
  1. 可見,官方推薦的做法是將整個jar文件解壓,在Dockerfile中多次用COPY命令分別複製,這樣做的好處顯而易見:多個layer,如果鏡像的新版本中只修改了應用代碼,那麼下載鏡像時只會下載/app這個layer,其他部分直接使用本地緩存,這是docker鏡像的常規優化手段;
  2. 上述方案有個小問題:麻煩!!!
  3. 於是2.3.0.RELEASE版本做了些優化,讓事情變得簡單些;

2.3.0.RELEASE版本方案和舊版的區別

2.3.0.RELEASE版本構建Docker的步驟如下:

  1. pom.xml中的spring-boot-maven-plugin插件增加一個配置項;
    2.編譯構建生成jar;
  2. 編寫Dockerfile,裏面用到了多階段構建(multi-stage builds),用工具從jar中提取拆分后,再多次執行COPY命令將拆分后的內容放入鏡像,達到多個layer的目的;

因此,2.3.0.RELEASE版本和舊版本相比有如下變化:

  1. pom.xml中多了個參數;
  2. 構建好jar后,無需自己解壓jar;
  3. Dockefile內容不一樣,舊版是手動解壓jar,再在Dockerfile分別複製,2.3.0.RELEASE是通過java命令從jar中提取出各部分內容

搞清楚了新舊版本的區別,咱們繼續研究下一個問題吧;

pom.xml中spring-boot-maven-plugin插件新增的參數

  1. pring-boot-maven-plugin插件新增參數如下圖所示:

2. 上述參數有啥用?我這邊編譯構建了兩次jar,第一次有上述參數,第二次沒有,將兩次生成的jar解壓后對比,發現用了上述參數后,生成的jar會多出下圖紅框中的兩個文件:

  1. 看看layers.idx文件的內容,如下圖:
  1. 上圖中的內容分別是什麼意思呢?官方已給出了詳細解釋,如下圖紅框:
  1. 綜上所述,layers.idx文件是個清單,裏面記錄了所有要被複制到鏡像中的信息,接下來看看如何使用layers.idx文件,這就涉及到jar包中新增的另一個文件:spring-boot-jarmode-layertools-2.3.0.RELEASE.jar

spring-boot-jarmode-layertools工具

  1. 前面已經介紹過jar中除了layers.idx,還多了個文件:spring-boot-jarmode-layertools-2.3.0.RELEASE.jar ,來看看這個文件的用處;
  2. 進入工程的target目錄,這裏面是編譯后的jar文件(我這裏文件名為dockerlayerdemo-0.0.1-SNAPSHOT.jar),注意此時的spring-boot-maven-plugin插件是帶上了下圖紅框中的參數的:
  1. 執行以下命令:
java -Djarmode=layertools -jar dockerlayerdemo-0.0.1-SNAPSHOT.jar list
  1. 得到結果如下圖所示,是layers.idx文件的內容:
  1. 來看看官方對這個layertools的解釋,list參數的作用上面我們已經體驗過了,重點是紅框中的extract參數,它的作用是從jar中提取構建鏡像所需的內容:
  1. 看到這裏,您是否想到了《體驗SpringBoot(2.3)應用製作Docker鏡像(官方方案)》中Dockerfile的內容,請看下圖的紅框和紅字,是否有種恍然大悟的感覺:jar構建生成清單layers.idx,Dockerfile中根據清單從jar提取文件放入鏡像:

至此,三個問題都已經找到了答案,小結一下:

SpringBoot-2.3.0.RELEASE推薦的鏡像構建方案和舊版本相比有什麼不同

  1. pom.xml中的spring-boot-maven-plugin插件增加一個配置項;
  2. 構建好jar后,舊版本要自己解壓jar,新版不需要;
  3. 新版本的jar中,多了個文件清單layers.idx和鏡像文件處理工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar
  4. 舊版的Dockefile內容:因為前面解壓好了,所有在Dockerfile里直接複製前面解壓的內容,這裏就有個風險:前一步解壓和當前複製的文件位置要保證一致;
  5. 新版的Dockerfile內容:使用工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar,根據的layers.idx內容從jar中提取文件,複製到鏡像中;
  6. 新版的Dockerfile中,由於使用了分階段構建,因此從jar提取文件的操作不會保存到鏡像的layer中;

pom.xml中spring-boot-maven-plugin插件新增的參數,到底做了什麼

spring-boot-maven-plugin插件新增的參數,使得編譯構建得到jar中多了兩個文件,如下圖所示:

Dockerfile中,java -Djarmode=layertools -jar application.jar extract這個操作啥意思

  1. java -Djarmode=layertools -jar application.jar extract的作用是從jar中提取文件,這些文件是docker鏡像的一部分;
  2. 上述操作的參數是extract,另外還有兩個參數,官方解釋它們的作用如下:

至此,問題已全部澄清,相信您對SpringBoot-2.3.0.RELEASE官方的鏡像構建方案也足夠了解了,最後是我根據自己的認識畫的流程圖,幫助您快速理解整個構建流程:

歡迎訪問我的GitHub

  • 地址:https://github.com/zq2599/blog_demos
  • 內容:原創文章分類匯總,及配套源碼,涉及Java、Docker、K8S、DevOPS等

歡迎關注我的公眾號:程序員欣宸

https://github.com/zq2599/blog_demos

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

【其他文章推薦】

※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※超省錢租車方案

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

※推薦台中搬家公司優質服務,可到府估價

分類
發燒車訊

小師妹學JavaIO之:文件系統和WatchService

目錄

  • 簡介
  • 監控的痛點
  • WatchService和文件系統
  • WatchSerice的使用和實現本質
  • 總結

簡介

小師妹這次遇到了監控文件變化的問題,F師兄給小師妹介紹了JDK7 nio中引入的WatchService,沒想到又順道普及了一下文件系統的概念,萬萬沒想到。

監控的痛點

小師妹:F師兄最近你有沒有感覺到呼吸有點困難,后領有點涼颼颼的,說話有點不順暢的那種?

沒有啊小師妹,你是不是秋衣穿反了?

小師妹:不是的F師兄,我講的是心裏的感覺,那種莫須有的壓力,還有一絲悸動纏繞在心。

別繞彎子了小師妹,是不是又遇到問題了。

更多精彩內容且看:

  • 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

更多內容請訪問www.flydean.com

小師妹:還是F師兄懂我,這不上次的Properties文件用得非常上手,每次修改Properties文件都要重啟java應用程序,真的是很痛苦。有沒有什麼其他的辦法呢?

辦法當然有,最基礎的辦法就是開一個線程定時去監控屬性文件的最後修改時間,如果修改了就重新加載,這樣不就行了。

小師妹:寫線程啊,這麼麻煩,有沒有什麼更簡單的辦法呢?

就知道你要這樣問,還好我準備的比較充分,今天給你介紹一個JDK7在nio中引入的類WatchService。

WatchService和文件系統

WatchService是JDK7在nio中引入的接口:

監控的服務叫做WatchService,被監控的對象叫做Watchable:

WatchKey register(WatchService watcher,
                      WatchEvent.Kind<?>[] events,
                      WatchEvent.Modifier... modifiers)
        throws IOException;
WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events)
        throws IOException;

Watchable通過register將該對象的WatchEvent註冊到WatchService上。從此只要有WatchEvent發生在Watchable對象上,就會通知WatchService。

WatchEvent有四種類型:

  1. ENTRY_CREATE 目標被創建
  2. ENTRY_DELETE 目標被刪除
  3. ENTRY_MODIFY 目標被修改
  4. OVERFLOW 一個特殊的Event,表示Event被放棄或者丟失

register返回的WatchKey就是監聽到的WatchEvent的集合。

現在來看WatchService的4個方法:

  1. close 關閉watchService
  2. poll 獲取下一個watchKey,如果沒有則返回null
  3. 帶時間參數的poll 在等待的一定時間內獲取下一個watchKey
  4. take 獲取下一個watchKey,如果沒有則一直等待

小師妹:F師兄,那怎麼才能構建一個WatchService呢?

上次文章中說的文件系統,小師妹還記得吧,FileSystem中就有一個獲取WatchService的方法:

public abstract WatchService newWatchService() throws IOException;

我們看下FileSystem的結構圖:

在我的mac系統上,FileSystem可以分為三大類,UnixFileSystem,JrtFileSystem和ZipFileSystem。我猜在windows上面應該還有對應的windows相關的文件系統。小師妹你要是有興趣可以去看一下。

小師妹:UnixFileSystem用來處理Unix下面的文件,ZipFileSystem用來處理zip文件。那JrtFileSystem是用來做什麼的?

哎呀,這就又要扯遠了,為什麼每次問問題都要扯到天邊….

從前當JDK還是9的時候,做了一個非常大的改動叫做模塊化JPMS(Java Platform Module System),這個Jrt就是為了給模塊化系統用的,我們來舉個例子:

public void useJRTFileSystem(){
        String resource = "java/lang/Object.class";
        URL url = ClassLoader.getSystemResource(resource);
        log.info("{}",url);
    }

上面一段代碼我們獲取到了Object這個class的url,我們看下如果是在JDK8中,輸出是什麼:

jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/Object.class

輸出結果是jar:file表示這個Object class是放在jar文件中的,後面是jar文件的路徑。

如果是在JDK9之後:

jrt:/java.base/java/lang/Object.class

結果是jrt開頭的,java.base是模塊的名字,後面是Object的路徑。看起來是不是比傳統的jar路徑更加簡潔明了。

有了文件系統,我們就可以在獲取系統默認的文件系統的同時,獲取到相應的WatchService:

WatchService watchService = FileSystems.getDefault().newWatchService();

WatchSerice的使用和實現本質

小師妹:F師兄,WatchSerice是咋實現的呀?這麼神奇,為我們省了這麼多工作。

其實JDK提供了這麼多類的目的就是為了不讓我們重複造輪子,之前跟你講監控文件的最簡單辦法就是開一個獨立的線程來監控文件變化嗎?其實…..WatchService就是這樣做的!

PollingWatchService() {
        // TBD: Make the number of threads configurable
        scheduledExecutor = Executors
            .newSingleThreadScheduledExecutor(new ThreadFactory() {
                 @Override
                 public Thread newThread(Runnable r) {
                     Thread t = new Thread(null, r, "FileSystemWatcher", 0, false);
                     t.setDaemon(true);
                     return t;
                 }});
    }

上面的方法就是生成WatchService的方法,小師妹看到沒有,它的本質就是開啟了一個daemon的線程,用來接收監控任務。

下面看下怎麼把一個文件註冊到WatchService上面:

private void startWatcher(String dirPath, String file) throws IOException {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path path = Paths.get(dirPath);
        path.register(watchService, ENTRY_MODIFY);

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                watchService.close();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }));

        WatchKey key = null;
        while (true) {
            try {
                key = watchService.take();
                for (WatchEvent<?> event : key.pollEvents()) {
                    if (event.context().toString().equals(fileName)) {
                        loadConfig(dirPath + file);
                    }
                }
                boolean reset = key.reset();
                if (!reset) {
                    log.info("該文件無法重置");
                    break;
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }

上面的關鍵方法就是path.register,其中Path是一個Watchable對象。

然後使用watchService.take來獲取生成的WatchEvent,最後根據WatchEvent來處理文件。

總結

道生一,一生二,二生三,三生萬物。一個簡簡單單的功能其實背後隱藏着…道德經,哦,不對,背後隱藏着道的哲學。

本文的例子https://github.com/ddean2009/learn-java-io-nio

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/java-io-file-watchservice/

本文來源:flydean的博客

歡迎關注我的公眾號:程序那些事,更多精彩等着您!

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

【其他文章推薦】

※回頭車貨運收費標準

※產品缺大量曝光嗎?你需要的是一流包裝設計!

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

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

分類
發燒車訊

買SUV就圖個高大帥氣!20萬要買SUV你怎麼也得考慮這幾款

廣汽菲克Jeep-自由光 指導價:20。98-31。58萬如果要數國產化之後表現會比進口版還要優秀的車子,叫獸相信廣汽菲克Jeep自由光算是一輛。國產的自由光在動力匹配和車廂隔音這兩個方面都比進口版的自由光要優秀,實際上在國產中型SUV市場上,自由光也算是一位表現出色的傢伙。

前段時間,二胎政策的放鬆,不少家用車消費者一下子都把目光投向了七座車上面,然而實際上坐滿七個座位的情況真的不多,而且很多時候七座SUV的第三排都是雞肋,成年人坐進去就會很憋屈。所以何苦為難自己和乘客?一輛大五座的汽車其實更加適合我們的日常使用,這甚至已經逐漸變成一種潮流。今天就和看看有哪些大五座的SUV值得我們關注吧。

上汽通用別克-昂科威 指導價:20.99-34.99萬元

昂科威是比較早期的“大五座”SUV,其實以昂科威的車身尺寸,要做七座車型並不是不可以,但它偏偏以座位布置上的差異與同價位的競爭對手漢蘭達錯位競爭,為自己創造出更大的生存空間,而後來火爆的銷量也說明了昂科威的路線是正確的。

外觀上,昂科威的造型飽滿修長又不乏時尚感,大氣得來又不會太老土,這樣的風格符合大部分消費者的審美。飽滿的前臉毫無疑問的採用了別克家族的網瀑式格柵,頗顯霸氣,大燈為氙氣光源並帶透鏡和LED燈帶,大燈造型和車身的匹配也毫無違和感。至於側面和車尾就以簡潔為主了,但是前後的線條在布局上互相溝通,整體感很強。

別克在車廂內飾豪華感的營造上可謂是業界的老手了,用料方面,上方的搪塑材料、中間的木紋飾板以及包圍的真皮面料,絲毫沒有怠慢;而設計上也不低調,懷抱式的布局加寬大的扶手,非對稱式的中控台,按鍵的布局也很合理,既有層次感又實用。多媒體方面,搭載了安吉星系統,支持手機互聯和導航等,功能豐富。

空間方面,調整好座椅以後,身高178cm的體驗者在駕駛位能取得一拳的頭部空間,在後排則有三指的頭部和一拳四指的腿部空間。值得一提的是昂科威的後排地板是全平的,而且後排座椅靠背也可以調節,只是可惜在頭部空間方面稍顯局促。

動力方面,昂科威搭載1.5T+七速雙離合或者2.0T+6AT的動力系統,最大馬力分別是169ps和260ps,1.5T車型的話動力還是稍失從容,畢竟馬力和車重都擺在那,需要拉高轉速來維持較理想的動力輸出,雙離合的低速頓挫則依舊存在,且對急加速的響應不夠迅速。相對來說,2.0T版本無論是動力強度還是變速箱的表現都要從容穩定更多,動力輸出流暢有後勁,所以更推薦2.0T的昂科威。

廣汽本田-冠道 指導價:26.98-32.98萬元

冠道這款車還未上市的時候就已經賺足眼球了,畢竟它是本田在國內的第一款中型SUV,但同時,冠道身上又集合了很多新技術,如2.0T的地球夢發動機,以及ZF的9AT變速箱,都是第一次出現在國內的本田車上,所以該車自然就吸引了不少的眼球了。

冠道的外觀硬朗且有肌肉感,雖然車身的高度略矮,但給人的感覺還是很壯碩的。中網寬大的鍍鉻飾條和車身造型很匹配,共同營造出冠道的“大塊頭”形象。細節處也頗具心思,如LED大燈、LED日行燈等的加入,側面的三條曲線更凸顯了車身的肌肉感,至於車尾的設計就稍顯普通,但是LED尾燈和雙排氣的設計還是不輸氣勢的。

內飾方面,冠道採用了懸浮式的中控屏和按鍵式排擋設計,科技感十足,同時用料方面也不會十分寒酸,中控台上方採用搪塑+縫線的設計,中間也加入了仿木紋啞光飾板,檔次感更強。而配置方面,座椅加熱和通風、手機互聯、HUD、車道偏離預警等功能都一應俱全,頗有豪華車的風範。

至於空間就是冠道的一大優勢了,前排調整好坐姿之後,身高182cm的體驗者在駕駛座仍有一拳一指的頭部空間,至於他去到後排之後,則有兩拳有餘的腿部和四指的頭部空間,空間表現十分寬裕,只是後排座椅靠背角度不支持調節,這有點可惜。

動力方面前面也提過,2.0T的發動機搭配采埃孚的9AT變速箱,最大馬力272ps,動力輸出比較線性,雖然不是很有爆發力的輸出,但信心還是很充足的,所以動力方面無需擔心。冠道底盤的舒適性也很值得肯定,濾震效果很徹底,但是時速60以上過彎的話,車輛的循跡性就會明顯下降,另外冠道對於高速行駛時遇到的顛簸還是處理得不夠從容,除此以外,冠道可以說本田有史以來隔音做得最好的車子了。

廣汽菲克Jeep-自由光 指導價:20.98-31.58萬

如果要數國產化之後表現會比進口版還要優秀的車子,叫獸相信廣汽菲克Jeep自由光算是一輛。國產的自由光在動力匹配和車廂隔音這兩個方面都比進口版的自由光要優秀,實際上在國產中型SUV市場上,自由光也算是一位表現出色的傢伙。

外觀尺寸方面,自由光比昂科威、冠道等同級對手要稍微小一點。但這也絲毫掩飾不了它的硬漢外形,全車身的黑色下包圍和七孔的豎狀中網,都凸顯了自由光作為一輛Jeep汽車該有的運動氣息,頗具特色的是七孔的中網還使用了曲折式的設計,比傳統的Jeep中網更有個性。

內飾方面,自由光並不像其他的Jeep車型那樣走硬朗的越野風,更多的是體現出一輛城市該有的細膩和豪華。中控台採用了軟質材料,而且上方有雙縫線工藝,提升了檔次感,真皮方向盤很粗壯,握感飽滿。多媒體方面,8.4英寸的Uconnect屏幕包含了導航、倒車影像等功能,功能上不會落後。

座椅的填充厚實,而且前排兩張座椅都有電動調節,算是順應了國內消費者的需求。空間方面,調整好坐姿之後,身高174cm的體驗者在前排有四指的頭部空間,在後排則有兩拳的腿部和兩指的頭部空間,可惜後排的地板凸起比較高,不利於中間位置的乘坐,所以自由光的後排空間表現只能算是中規中矩。

國產自由光的動力系統有兩種,分別是2.0L和2.4L的發動機,搭配9AT的變速箱,最大馬力分別是155ps和175ps,採用了全自然吸氣的班底,算是現時少有的了。兩個排量的自由光都不是以動力為賣點,而且變速箱的降擋反應並不积極,僅能滿足日常的駕駛,所以2.0L的自由光並不適合激烈的駕駛。底盤則偏向於城市SUV的調校,偏向舒適且濾震效果不錯。

上汽大眾斯柯達-柯迪亞克預計上市時間:2017年夏季

斯柯達和大眾之間有着一些微妙的關係,一般這兩個品牌同一時期的同級別同平台車輛的話,先上市的一般是斯柯達的車,速派和邁騰就是這種關係。而在中型SUV領域,柯迪亞克和新途觀之間也是類似的這種微妙關係。至於个中原因,就是大眾決策層的經營策略了,我們也不好猜測。

還是先把注意力放回柯迪亞克身上吧,從“Kodiaq”的名字我們就會知道這輛車的體型不會小,而且外觀風格也會比較硬朗,實際也是如此。前臉雖然依舊是斯柯達家族式的中網,但線條會更加硬朗,而中網兩邊的大燈也是斯柯達首次使用的LED大燈,科技感十足。側面造型修長且硬朗,尾部造型則和速派旅行版相仿,家族氣息更濃,辨識度也不低。

來到內飾,熟悉MQB平台車輛(高爾夫7、速派)的人都不會感到陌生了,平直的線條、對稱式的布局,嚴謹的設計風格。但柯迪亞克的內飾還是比其他大眾系的車輛要顯得開揚一點,簡單說就是更大氣了。配置方面,常規B級車的駕駛輔助和舒適性方面的配置都沒有或缺,另外要說的是該車的儲物空間挺豐富的,而且加入了全景天窗,比較對消費者的胃口。

部分車型(估計是高配)座椅面料為Alcantara加真皮,看着顯檔次,坐着也舒適,比較喜歡這種座椅。空間方面,前排調整好之後,身高185cm的體驗者還能有一拳的頭部空間,而他去到後排則有一拳有餘的腿部和四指的頭部空間,這個表現對於普通身材的成年人來說已經足夠寬敞,不用擔心空間問題。

目前已知柯迪亞克會推出兩種動力系統,分別是1.8T和2.0T的排量,搭配7速DSG變速箱,最大馬力為180ps和220ps,動力表現和速派這類大眾車類似,起步時油門會稍顯慵懶,但隨着油門深度的加大,動力的充沛感會愈加明顯。底盤則維持了德系車紮實質感的基礎上會稍偏硬,但舒適性並不差,只是這種車體型大,方向盤也很輕,駕駛感不太明顯。

總結:越來越多的廠商重視“大五座”SUV這個細分市場,事實上大部分消費者在預算足夠的情況下都更願意買大點的車,至於七座與否,似乎並不是最重要的點。相對緊湊型車,這個級別有更多的空間來提升車輛的產品力,所以這也是建立品牌口碑的一個很好的途徑,相信中型SUV市場的競爭會越來越激烈,更多的好車也會不斷湧出。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

※台北網頁設計公司全省服務真心推薦

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

※推薦評價好的iphone維修中心

網頁設計最專業,超強功能平台可客製化

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