巴哥食慾減弱呈陽性反應恐為全美首隻確診寵物犬

摘錄自2020年4月29日自由時報報導

美國北卡羅萊納州有一隻巴哥犬被檢測出對武漢肺炎病毒呈陽性反應,恐為美國第一隻寵物犬確診案例。

《NBC》報導,該隻名叫溫斯頓(Winston)的巴哥其主人家庭有多人確診,男女主人和兒子均呈陽性反應,女兒、另一隻狗以及寵物貓則呈陰性反應。女主人麥可萊恩(Heather McLean)表示,溫斯頓有輕微症狀,早上沒有食慾。報導指出,該隻巴哥的家庭成員還透露,狗狗會舔遍所有的餐盤,然後跟主人一起睡覺。

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

【其他文章推薦】

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

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

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

※回頭車貨運收費標準

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

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

9萬起個性/運動 同級別操控最強A級車

99萬福克斯 2017款 三廂 EcoBoost 180 自動旗艦型 指導價16。58萬配置表現福克斯更勝一籌,雖然差價只在4100元,福克斯和思域相比配置更為豐富,方向盤換擋、SONY索尼揚聲器品牌、后視鏡電動摺疊、感應雨刷,自動泊車入位這些配置思域上並沒有。

前言隨着現在轎車市場越來越家用化,運動型轎車也變的不那麼運動了,更多是兼家用和運動,各佔一半,就變得不倫不類了,舒適性談不上,運動性能也是很一般,正所謂魚與熊掌不可得兼,根本也扯不到平衡,總要有一方更強勢。現在年輕消費者就佔據大半汽車市場,而年輕人更追求快感與操控,所以他們在空間取向並沒有上一輩人這麼注重。

東風本田-思域

指導價:11.59-16.99萬

長安福特-福克斯

指導價:9.98-16.58萬

外觀對比

全新一代思域可謂是改頭換面,無論是在外觀、動力都非常成功,在視覺效果可以說非常驚艷與時尚,車身線條十分運動,雖然延續了本田家族式設計,但整體看起來依然很年輕。

福克斯外觀設計,就談不上驚艷,來的更多是沉穩,就像一位斯斯文文眼鏡男,但衣服里藏里一大塊腹肌,是個有實力的选手。但在細節方面也做的不錯,動感車身線條,現在都流行“套臉”模式而福克斯也不例外,因為有了蒙迪歐這代車型,視覺效果並沒有太大衝擊。

內飾對比

思域內飾上雖然重新設計,但是塑料感依舊強烈,說它就是台飛度用料一點也不誇張,車廂用料方面反而福克斯更加厚道,中控檯面積採用大面積軟質材料包裹,但整體上思域內飾時尚,唯一缺憾用料吝嗇、福克斯個性,做工很厚道。

空間對比

本田,一個最會將空間玩的淋漓盡致的品牌,思域空間表現毋庸置疑,作為A轎車,無論是頭部還是膝部空間,都有很大余量。而福克斯空間依然是它短板,因為中控台較寬大,利用了不少車廂空間,所以在乘坐後排,坐長途不太舒適,但作為年輕人之選,這不影響他們的選擇。

配置對比

思域 2016款 220TURBO 自動尊耀版 指導價:16.99萬

福克斯 2017款 三廂 EcoBoost 180 自動旗艦型 指導價16.58萬

配置表現福克斯更勝一籌,雖然差價只在4100元,福克斯和思域相比配置更為豐富,方向盤換擋、SONY索尼揚聲器品牌、后視鏡電動摺疊、感應雨刷,自動泊車入位這些配置思域上並沒有。作為偏運動車型,連方向盤換擋都沒有,這個必須減分。配置上思域表現也並不差,全液晶儀錶盤、後座出風口、自動駐車、胎壓監測裝置等配置。

動力對比

兩款車型都搭載1.5T渦輪增壓發動機,動力表現兩者都幾乎相差無幾,傳動系統,福克斯配備6擋手自一體、思域則配備CVT無級變速箱。響應性,福克斯會更激進,思域平順性更高,思域雖然搭載CVT變速箱,這款變速箱我想大家也非常了解,但思域用上這套變速箱動力響應能兼顧平順的同時在動力輸出變現也不錯。

福克斯配備6AT變速箱,在急加速時,依然會思考下人生,隨後動力才湧現。行駛質感,福克斯更高級,底盤濾震處理相當不錯,底盤很紮實硬朗;思域,底盤很從容,行駛質感也較為舒服。隔音方面福克斯與思域相比更為高級。

編者總結:

這兩款車型,作為年輕買家來說,都是在考慮範圍內,無論是動力外觀兩者都有不錯的表現,福克斯操控方面略強,但空間是它唯一短板,思域在綜合表現比福克斯更好,空間外觀都比福克斯更好。如果追求操控在空間並沒有太多需求則選福克斯,而追求動力的同時需要較大空間就選思域。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

※超省錢租車方案

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

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

※回頭車貨運收費標準

從5到100萬全都有 2017年這些爆款SUV就要來啦

雪佛蘭 – 探界者預計售價:18萬起預計上市日期:2017年近幾年來,雪佛蘭幾乎只有一款創酷在征戰SUV市場(老舊的科帕奇可以忽略不計),要想進一步提升銷量,推出一款全新的SUV勢在必行,於是就有了這台探界者。福特有探險者和撼路者,雪佛蘭搞出個探界者是什麼鬼。

持續了近10天的2016廣州國際車展終於在上周日謝幕,在不少媒體老濕吐槽本屆車展沒有太多亮點的時候,叫獸卻發現了另一番風景:

好了,說回正題,這屆車展雖然看點不多,甚至除了媒體日那天可憐的日產外(你懂的),都沒有太多可以調侃的段子,但以下這些SUV的登場還是給叫獸帶來不少驚喜。廢話結束,接下來看看在即將到來的2017年有哪些SUV是值得我們期待的。

寶駿 – 510

預計售價:5.5 – 8萬

上市日期:預計2017年1季度

我把寶駿510排在第一位,其預計的親民售價是第一點,最最重要的還是它擁有堪稱驚艷的外觀設計。如果不是親眼所見,真不敢相信這居然是寶駿出品的一款車。

犀利、個性、時尚、前衛···這一些列詞彙悉數冠在510身上也毫不為過,sorry,原諒叫獸任性一回,僅憑外觀就愛上了這款車。不過在感性之餘,咱們回歸到理性部分。

510的內飾同樣令人稱讚,雖談不上有多麼精緻,但看上去毫不雜亂,算得上是簡潔大方,這對一款入門車型來說是難能可貴的。

從前两天有關510文章的評論里可以看出,大家對這款車都很期待。叫獸斷言,只要未來的價格給力,這又將是一款爆款的存在。小道消息稱,510將於2017年1季度上市。

名爵 – ZS

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

【其他文章推薦】

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

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

※超省錢租車方案

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

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

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

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

捂緊錢包!12月開始這些又高又大的SUV準備來圈錢了!

長寬高達到4949/1930/1785mm,軸距也達到2810mm,數據不亞於同級別競爭對手。新車提供5座和7座版本車型,其中7座採用2+3+2的座椅布局。而在長安CS95眾多的產品賣點的重中之重,都放在這台2。0TGDI發動機,最大馬力為233ps,最大扭矩360Nm,官方百公里加速為9。

隨着家庭人口的增多,以及消費層次的升級,7座SUV逐漸成為SUV市場中不可忽視的一股消費主力。特別是傳祺GS8的上市,不只是成功聚焦了眾人的眼光,更是讓消費者重新定義了屬於7座SUV的魅力。於是,在利益和現實因素的推動下,越來越多的車企瞄準了7座SUV市場紛紛出大招。

相比傳統的5座SUV,其實市面上7座SUV的產品線非常單薄,以致於寡頭垄斷的局面曾經持續了很長一段時間。事實上,隨着7座SUV這一細分市場的升溫,除了考慮漢蘭達、銳界、傳祺GS8,你還可以考慮這些即將上市的7座SUV。

金杯蒂阿茲

預售價:8.68萬元

上市時間:2016年12月

大部分對於華晨金杯的印象,還停留在爛大街的商務車上。而近期亮相的金杯蒂阿茲,可謂完全“刷新”了國人對於金杯的認識。一眼望去,如果不仔細加以辨認,還以為是套上金杯logo的謳歌MDX。當然,外觀方面是懂的人自然懂。更何況,不到9萬的預售價已經相當有吸引力了。

內飾方面中規中矩,但好在配置應該比較豐富。新車搭載一台1.5T發動機,最大馬力154ps,峰值扭矩 210Nm。先期預計將推出一款手動擋5座車型,而準備購買自動擋以及7座版車型的消費者,或許還要等到明年才有機會下手。

長安CS95

預售價:未知

上市時間:2017年第一季度

繼哈弗、傳祺推出了7座SUV之後,長安CS95量產版也終於按耐不住選在這個節骨眼亮相。有意思的是,之前飽受吐槽的“回”字前臉,總算是被重新修飾了一番,整體效果看起來不錯。車身形象高大威猛,好一副硬派SUV的作風。這裏也不得不提到長安CS95的戰略意義,目前是被長安用來衝擊高端的首款中型SUV,產品力可想而知。

即然是一台全尺寸旗艦SUV,長安CS95的車身尺寸沒有讓人失望。長寬高達到4949/1930/1785mm,軸距也達到2810mm,數據不亞於同級別競爭對手。新車提供5座和7座版本車型,其中7座採用2+3+2的座椅布局。而在長安CS95眾多的產品賣點的重中之重,都放在這台2.0TGDI發動機,最大馬力為233ps,最大扭矩360Nm,官方百公里加速為9.8秒。

起亞KX7

預售價:未知

上市時間:2017年3月

迫不及待加入7座SUV戰場的,還有來自韓國的起亞。據悉,全新起亞KX7是基於上一代索蘭托平台開發,簡單理解而言又是一台中國特供車。新車繼續沿用家族式設計語言,造型穩重大氣,又不失時尚感。就外觀來講,起亞KX7顯然是非常符合國人的審美觀念的。

但看看起亞KX7整體的車身尺寸,一比較2790mm的漢蘭達和2850mm的銳界,軸距僅為2700mm的起亞KX7的產品短板就非常明顯了,尤其是第三排座椅舒適度會是一個很大障礙。不過,從起亞KX7所公布的配置情況,再結合韓系車一向的低價傳統,上市后的起亞KX7預計仍將通過高性價比的策略,力爭7座SUV市場份額。

大眾Teramont

預售價:未知

上市時間:2017年上半年

國產大眾途觀明年上市的消息,就已經讓多少大眾粉朝思暮想。與此同時,另一款大眾重磅車型的亮相再次引爆人們的話題點,那就是全新中大型SUV-大眾 Teramont。新車延續了大眾CrossBlue概念車的設計,形象霸氣魁梧,視覺上極具震撼力。

更牛逼的是,車身尺寸已經大大超過途銳,幾乎與奧迪Q7旗鼓相當,長寬高為5039/1989/1773mm,軸距也順利達到逆天的2980mm。就180cm大個子的體驗,無論是第二排還是第三排,空間可以用大到沒朋友形容。動力總成也非常給力,大眾Teramont採用2.0T高低功率版以及2.5T V6發動機,匹配7速濕式雙離合變速箱。如果不出意外,配合一個合理厚道的價位,以及大眾的神車光環,大眾Teramont大賣不成問題。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

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

這些不少人都想買的自主SUV都使用日系的變速箱你知道嗎?

東風AX7指導價格:9。97-14。17萬東風風神AX7是基於東風軍工二號平台生產的首款民用SUV車型,在做工品質上還是有着一定的高質量保證,同樣藉助多年與國外知名汽車企業合資的資源性便利,東風AX7在汽車配件供應商方面也是來頭不小。
採用愛信變速箱的自主SUV
最近小編收到不少的網友留言,問題的主要偏重點在於:中國自主品牌當中的SUV有哪些採用愛信變速箱?或者愛信變速箱為什麼那麼多人採用?那麼今天就帶着問題,看看愛信變速箱究竟有什麼優勢讓這麼多人採用。
愛信變速箱可以說是現在汽車市場中的明星產品系列,不少情況下都會聽到“XX車使用了愛信變速箱”的話語,那麼究竟為什麼它的受眾面會這麼廣?
品牌成熟,技術可本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

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

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

8萬到30萬,這幾款車的發動機值得推薦,有力又省油!

上汽通用五菱-寶駿 5602016款 1。5T 手動舒適型售價:8。18萬元東南-DX32016款 1。5T CVT舒適型售價:8。49萬元斯柯達-速派2016款 280TSI DSG前行版售價:17。98萬元廣汽謳歌-CDX2016款 1。5T 兩驅暢享版售價:22。98萬元總結:8萬到30萬區間里值得購買的幾款小排量四缸渦輪增壓發動機車型都為你一一推薦,看個人預算和需求辦事,總能選出最合適你的那款車。

隨着6缸發動機漸漸退出家用車舞台,當代車企越來越注重汽車的排放和燃油經濟性。在排放、購置稅等政策影響下催生出以前不敢想象的三缸1.0T發動機,雖說三缸發動機擁有着燃油經濟性和排放的先天優勢,福特、吉利等廠商當起了先行者,但礙於發動機振動和噪聲抑制以及動力儲備的上限,始終難登大雅之堂。而大排量V6發動機制肘於大油耗和購置稅政策,終究被家用車市場淘汰。

要照顧到行駛質感和動力的同時,又要理想的燃油經濟性和享受購置稅優惠政策,要求敢不敢再多點?不要緊,給你支招,咱可以選四缸1.5L及以下排量的渦輪增壓車,下面給你推薦各個價位區間符合以上要求的車型。

上汽通用五菱-寶駿 560

2016款 1.5T 手動舒適型

售價:8.18萬元

東南-DX3

2016款 1.5T CVT舒適型

售價:8.49萬元

斯柯達-速派

2016款 280TSI DSG前行版

售價:17.98萬元

廣汽謳歌-CDX

2016款 1.5T 兩驅暢享版

售價:22.98萬元

總結:8萬到30萬區間里值得購買的幾款小排量四缸渦輪增壓發動機車型都為你一一推薦,看個人預算和需求辦事,總能選出最合適你的那款車。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

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

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

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

年輕人首選的SUV?這次給你們推薦點不一樣的

而本次所介紹的東南DX3則是東南品牌旗下的“小鮮肉”車型,外觀造型與DX7師出同源,由於車身更加短小緊湊,所以可以看出東南DX3的外觀更加具有時尚感和運動感,作為一款消費人群定義在三十歲以內年輕人的車型,東南DX3的顏值可以獲得一個比較高的分數。

年輕人首選的自主品牌SUV

現在年輕人購車已經不是什麼稀奇的事情,但是似乎業內出現了一種怪圈,就是說到年輕人首選的SUV車型,合資的似乎就只有通用集團的昂科拉、創酷;而自主品牌就只有吉利在今年新推出的跨界SUV帝豪GS,其實不然,在自主品牌中,還是有不少年輕人可以選擇的SUV。

為什麼要推薦自主品牌?

當手機逐漸智能化並且豐富了人們的生活之時,國產品牌的手機成為了市場的新寵,功能強大,價格實惠的國產品牌手機使用基數往往比國際知名品牌手機要來得多;反觀汽車也是如此,消費者更注重的是一台車的售價和配置,而逐步成長起來的自主品牌汽車未嘗不能成為預算通常不太多的年輕人首選的車型。

如果當一輛SUV品牌實力強勁,售價相對實惠,外觀還富有個性的話,作為購置第一台車以便於初入職場實現人生目標的年輕消費者來說,自然是一種不錯的選擇。

BJ20

指導價格:9.68-13.98萬

北京汽車是自主汽車較早出名的品牌之一,在上世紀八十年代左右的北京,如果誰可以開着一台“北京吉普”在大街上“招搖過市”,那絕對是拉風至極的一件事情。

而在今年中旬,北京汽車專門為年輕一代的消費者推出了一款城市SUV——BJ20,整車在外觀設計上繼承了北京汽車品牌家族式的經典元素,並且根據時下流行的審美趨勢進行融合,使得BJ20的外觀極具個性與硬派氣息。

內飾設計同樣看得出北京汽車的品牌形象已經逐漸成熟,家族化風格十分濃郁,平直簡練的風格配合上獨特的雙幅式方向盤造型,穩重中還透露出一絲個性與不羈。

BJ20搭載的是一台1.5T渦輪增壓發動機,最大馬力150匹,峰值扭矩210牛米,與之配合的是傳統的手動變速箱和一台CVT無級變速箱;儘管不帶四驅,但是超越同級別的底盤高度,在應對稍微惡劣的非鋪裝路面時還是能給予人不少的信心。

東南DX3

指導價格:6.79-10.09萬

東南也算是國內做SUV車型比較有歷史的汽車廠商了,之前與三菱的深度合作使得東南在造車方面有了一定的技術深度儲備,而且近年來與賓法合作,在外觀設計上也逐漸有了自己的風格和語言,東南DX7則算是一台掙回了眼球的SUV。

而本次所介紹的東南DX3則是東南品牌旗下的“小鮮肉”車型,外觀造型與DX7師出同源,由於車身更加短小緊湊,所以可以看出東南DX3的外觀更加具有時尚感和運動感,作為一款消費人群定義在三十歲以內年輕人的車型,東南DX3的顏值可以獲得一個比較高的分數。

內飾設計同樣讓人覺得印象深刻,方形幾何配合圓形出風口的造型挺富有視覺衝擊力,只是有一點小編不太能理解的是,為何多媒體中控的功能性操控按鍵會放置在副駕駛的一側?這在國內的在售量產車型上見得確實不多。

畢竟是與三菱有過深度合作的歷史,東南DX3採用的是源自三菱的兩款發動機,型號同為4A91,1.5T發動機最大馬力156匹,峰值扭矩220牛米,1.5L發動機最大馬力120匹,峰值扭矩143牛米,傳動系統是一款可模擬八個檔位,來自比利時邦奇的CVT變速箱,邦奇也是目前國內採用CVT變速箱的車型主要供應商之一。

寶駿510

指導價格:暫無(猜測6-8萬)

寶駿汽車相繼使用了730和560兩款車型打開了銷量之後,最近開始將目標消費群體轉向年輕人群,先是推出了一款售價實惠的兩廂轎車寶駿310,而今年廣州車展上發布的一款年輕定位的SUV也有可能成為未來的主力,那便是寶駿510,。

外觀層面寶駿510非常聰明的使用了當下流行的設計元素,前大燈分體式設計很容易使人聯想到自由光,多邊形的進氣格柵和懸浮式車頂的設計也是觀眾們非常熟悉的設計語言,但是這些融合在寶駿510的身上顯得挺和諧。

內飾層面採用的雙色拼接方式同樣顯得年輕運動,組合型的幾何板塊配合上啞光的裝飾,整個車廂氛圍營造得恰到好處。獨立式的多媒體显示屏幕也算是內飾當中比較出彩的亮點。

動力層面寶駿510搭載的是與寶駿730相同的1.5L自然吸氣發動機,最大馬力112匹,峰值扭矩147牛米,目前僅有6速手動變速箱,未來是否會換上與730相同的AMT變速箱暫時不得而知。

寶駿510的售價暫時沒有公布,但是從小型SUV的定位上看,會比6.98-9.48萬元定價的寶駿560要稍微低一些,小編大膽猜測頂配價格應該是在8萬元左右。究竟最終售價如何,還是比較值得期待。

全文總結:現在年輕一代的汽車消費群體逐漸在全國各地湧現,不僅僅是經濟較為發達的一線城市,在很多二三線甚至更低定位的城市當中,汽車也已經成為了人們日常生活的重要工具,擁有一輛自己的車也是很多年輕人普遍擁有的想法,而面對着現在不斷成熟完善的自主品牌,購買一台自主品牌車型作為人生首輛車,小編認為也沒什麼不好。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

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

10月銷量達7千多輛!8.98萬起這款日產技術SUV值得買嗎?

38萬車主點評:最滿意空間,乘坐空間很夠用。還有一次有個朋友喝多了,像爛泥一樣一動不動,我們直接把他抬到後備廂里拉回去。動力方面,捨得給油還是有推背感,不過開空調載着4個人,就顯得力不從心啦。目前行駛里程:我目前開了3980公里,平均百公里油耗只有6。

東風日產-啟辰T70

指導價:8.98-12.78萬

車主:神車奧拓

購買車型:2016款 2.0L CVT睿行版

裸車價格:9.78萬

車主點評:我最滿意它的底盤紮實,懸挂行程長,所以通過性好,另外它對於震動的過濾不錯。而內飾的硬塑料有點多!所以檔次感就不夠了。

目前行駛里程:我的T70買了才兩個月,跑了有1345公里,平均百公里油耗只有8.2L,我覺得CVT變速箱還是比較省油!

車主:笑出12塊腹肌

購買車型:2016款 1.6L 手動睿行版

裸車價格:8.38萬

車主點評:最滿意空間,乘坐空間很夠用。還有一次有個朋友喝多了,像爛泥一樣一動不動,我們直接把他抬到後備廂里拉回去!動力方面,捨得給油還是有推背感,不過開空調載着4個人,就顯得力不從心啦!

目前行駛里程:我目前開了3980公里,平均百公里油耗只有6.9L,手動擋相當省油。

車主:段迎風

購買車型:2015款 2.0L CVT睿趣版

裸車價格:11.50萬

車主點評:開起來其實類似日產逍客的感覺,底盤比較紮實。空間的表現也讓我給它豎起大拇指!動力感覺有點肉,這是日產CVT變速箱的特性。另外方向盤有些重,開起來比起本田繽智還是顯得笨重一些。

目前行駛里程:我的車是2015年12月購買的,到現在行駛了9500公里,平均百公里油耗9L,這樣的油耗還可以接受。

編者點評:

啟辰T70的價格不高,但是在底盤表現、質量、空間方面表現都不錯,只是配置會稍低一些。綜合性價比是不錯的!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※回頭車貨運收費標準

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

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

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

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

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

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

讀懂操作系統之緩存原理(cache)(三)

前言

本節內容計劃是講解TLB與高速緩存的關係,但是在涉及高速緩的前提是我們必須要了解操作系統緩存原理,所以提前先詳細了解下緩存原理,我們依然是採取循序漸進的方式來解答緩存原理,若有敘述不當之處,還請批評指正。

緩存原理

高速緩存被劃分為多個塊,其大小可能不同,緩存中的塊數通常為2的冪。如下為一個具有八個塊的高速緩存,每個塊包含一個字節。

通過本節對緩存原理的學習我們能夠學習到四點:

【1】當我們將數據塊從主存儲器複製到緩存,我們到底應該放在哪裡?

【2】如何判斷一個字是否已經在緩存中,或者它是否必須首先從主存儲器中獲取?

【3】較小的緩存最終會填滿, 需要至從主存加載新塊,我們必須替換緩存中現有的哪個塊?

【4】存儲系統如何處理寫操作?

數據放在緩存哪裡?

緩存最簡單的數據結構是直接映射: 其中每個存儲器地址僅僅對應到緩存中的一個位置。例如如下,16個字節的主存和4個字節的緩存(每個塊一個字節),內存地址為0、4、8、12分別映射到緩存中為0的塊,而地址1、5、9、13被映射到塊1

等等,我們是不是講解的太快了,上述地址怎麼就劃分到比如塊0或塊1了呢?要找出緩存所在塊採取取模法:(塊地址)mod (緩存中的塊數),如果緩存包含2k塊,則內存地址i處的數據將進入緩存塊索引為i mod 2k。還是不懂?我們來舉個例子,如下緩存有4個塊,那麼地址為14將映射到塊2即(14 mod 4 = 2)。

為便於大家理解如上為10進製表示內存地址,將內存地址映射到緩存塊中實際等效的方式是將內存地址中的最低有效k位(二進制)進行映射。正如下面我們所看到的,內存地址14(1110,二進制)將最低有效位10作為塊中的索引

怎樣找到緩存中數據?

到目前為止我們知道了將地址利用直接映射的結構映射到緩存中,那麼我們找到數據是否在緩存中呢?如果要讀取內存地址i,則可以使用mod技巧來確定哪個緩存塊將包含i,如上所述,若其他地址也可能映射到相同的緩存塊,那麼我們如何區分它們呢?例如如下內存地址2、6、10、14都在緩存塊2中

為了解決這個問題,我們需要向高速緩存中添加標記(tag),通過內存地址的高位來提供標記位,以使我們能夠區分映射到同一高速緩存塊的不同存儲位置。例如如下。內存地址6即(0110,二進制),將低位10作為索引(index),高位01作為標記(tag)。

我們通過將高速緩存塊標記(tag)與塊索引(index)組合起來,可以準確地知道主存儲器的哪些地址存儲在高速緩存中。

當程序加載到內存中時,緩存為空,不包含有效數據,我們應該通過為每個緩存塊添加一個有效位來解決這個問題,系統初始化時,所有有效位均設置為0,當數據加載到特定的緩存塊中時,相應的有效位設置為1。

當CPU嘗試從內存中讀取數據時,該地址將被發送到緩存控制器,地址的最低k位將在緩存中索引一個塊,如果該塊有效且標籤與m位地址的高(m-k)位匹配,則該數據將被發送到CPU,如下為一個32位內存地址和210字節高速緩存的圖。

到這裏我們會發現一個問題,將每一個字節對應一字節緩存塊並沒有很好的利用空間局部性,要是訪問一個地址后將訪問附近的地址,我們又該怎麼辦?我們要做的是將緩存塊的大小要大於1個字節。如下,我們使用兩個字節的塊,因此我們可以用兩個來加載緩存一次讀取一個字節,如果我們從內存地址12讀取數據,則地址中的數據12和13都將被複制到緩存塊2。

現在,我們又該如何確定數據應放在緩存中的位置?現在演變成塊地址,如果緩存塊大小為2n字節,我們也可以在概念上將主內存也劃分成2n字節塊,要確定字節地址i的塊地址,可以進行整數除法(i / 2n),如下示例中有2個字節的緩存塊,因此我們可以將16個字節的主存儲器視為8塊主存儲器,例如,存儲器地址12和13都對應於塊地址6,因為12 / 2 = 6和13 / 2 = 6。 

現在我們知道了塊地址,就可以像上述一樣將其映射到緩存:找到塊地址除以緩存塊數后的餘數。在如下示例中,內存塊6屬於緩存塊2,因為6 mod 4 =2,這對應於將來自存儲器字節地址12和13的數據都放入高速緩存塊2中。

當我們訪問內存中的一個字節數據時,我們會將其整個塊複製到緩存中以達到充分利用空間局部性。在我們的示例中,如果程序從字節地址12讀取,我們會將所有存儲塊6(地址12和13)都加載到緩存塊2中(注意:字節地址13對應於相同的存儲塊地址)因此,對地址13的讀取也會導致將存儲塊6(地址12和13)加載到高速緩存塊2中。為了簡化起見,存儲塊的字節i始終存儲在相應高速緩存塊的字節i中。

假設我們有一個包含2k塊的緩存,每個塊包含2n個字節,我們可以通過查看其在主內存中的地址來確定該緩存中一個字節的數據位置,地址的k位將選擇2k個高速緩存塊之一,最低的n位現在是一個塊偏移量,它決定了高速緩存塊中的2n個字節中的哪個將存儲數據。

我們來舉個例子加深理解,如下示例使用22塊高速緩存,每個塊佔21字節,因此,存儲器地址13(1101)將存儲在高速緩存塊2的字節1中。

到這裏為止,我們才算分析清楚了緩存中有效位、標記位、索引、偏移它們的由來以及實際作用。同時對於緩存採用的直接映射(direct mapped)結構:索引和偏移量可以使用位運算符或簡單的算術運算,因為每個內存地址都恰好屬於一個塊。實際上我們可以將一個塊放置到緩存中的任何一個位置,這種機制稱為全相聯(fully associative)。全相聯的高速緩存允許將數據存儲在任何高速緩存塊中,而不是將每個內存地址強制映射到一個特定的塊中,從內存中獲取數據時,可以將其放置在高速緩存的任何未使用塊中。 這樣,我們將永遠不會在映射到單個緩存塊的兩個或多個內存地址之間發生衝突,在上述示例中,我們可能將內存地址2放在緩存塊2中,並將地址6放在塊3中。然後對2和6的後續重複訪問將全部命中而不是未命中,如果所有塊都已被使用,則使用LRU算法進行替換。但是在全相聯緩存中要查找一個指定的塊,由於該塊存放在緩存中的任何位置,因此需要檢索緩存中的所有項,為了是檢索更加有效,它是由一個與緩存中每個項都相關的比較器并行完成的,這些比較器加大了硬件開銷,因而,全相聯只適合塊數較少的緩存。介於直接映射和全相聯之間的設計是組相聯(set associative)。在組相聯緩存中,每個塊可被放置的位置數固定,每個塊有n個位置可放的緩存被稱作n路組相聯,一個n路組相聯緩存由很多組組成,每個組有n個塊。通過上述對直接映射的講解,最終我們得出指定內存地址所在存儲的塊號為:(塊號) mod (緩存中的塊數),而組相聯對於存儲塊號是:(塊號) mod (緩存中的組數)。如下為8塊高速緩存的組織

組相聯實際上就是將塊進行分組,比如如上第一個圖則是直接映射(我們大可將其看做是每一個塊就是一個組,所以是1路8組相聯),而第二張圖則是每2個塊作為一組,所以是2路4組相聯,同理第三張圖是4路2組相聯。換句話說,若每組有2n塊,那麼就是2n路相聯。通過對組相聯的講解,我們再敘內存地址在組相聯緩存中的位置。如果我們有2s組並且每塊有2n字節,那麼內存地址映射在緩存中的位置則是如下這般

現在我們運算則是計算緩存中的組索引而非再是塊,上述Block offset(在組中塊偏移)= 內存地址 mod 2n,塊地址 = 內存地址 / 2n,set index(組索引) = 塊地址 mod 2s。我們還是通過圖解來進行敘述,假設有一個8塊的高速緩存,然後每個塊是16個字節,那麼內存地址為6195的數據存儲在緩存哪裡呢?首先我們將6195轉換為二進制  = 110000 011 0011,因每個塊是16字節即24,所以塊偏移量為4位即0011,若採用1路8組相聯(直接映射)那麼其組索引就是(6195 mod 8) = 3,取6195轉換而二進制去除偏移量4位,所以為011,同理(根據上述給定計算公式)對於2路4組相聯其組索引為(11),4路2組相聯其組索引為(1),如下:

到這裏我們知道將數據進行緩存我們可以採取直接映射、組相聯、全相聯的機制,通過增加相聯度通常可以降低緩存缺失率,但是增加相聯度也就增加了每組中的塊數,也就是并行查找時同時比較的次數,相聯度每增加兩倍就會使得每組中的塊數加倍而使得組數減半,所以增大了訪問時間的開銷。如何找到一個塊,當然也就依賴於所使用的將塊放置的機制(直接映射、組相聯、全相聯),相較於全相聯而言,它使用複雜的替換策略而降低缺失率且很容易被索引,而不需要額外的硬件,也不需要進行查找。因此虛擬存儲系統通常使用全相聯映射,而組相聯映射通常應用於緩存和TLB。

緩存缺失和寫操作

緩存缺失被分為以下三類(3C模型,three Cs model),因其三類名稱以字母c開頭而得名

強制缺失(compulsory miss):對從沒有在緩存中出現的塊第一次進行訪問引起的缺失,也稱為冷啟動缺失(cold-start miss)

容量缺失:(capacity miss):由於緩存容納不了一個程序執行所需要的所有塊而引起的緩存缺失,當某些塊被替換出去,隨後再被調入時,將發生容量缺失

衝突缺失(conflict miss):在組相聯或者直接映射的緩存中,多個競爭同一個組時而引起的緩存缺失。衝突缺失在直接映射或組相聯緩存中存在,而在同樣大小的全相聯緩存中不存在,這種緩存缺失也稱為碰撞缺失(collision miss)

改變緩存設計的某一方面就能直接影響這些缺失的原因。衝突缺失是因為爭用同一個緩存塊而引起的,因此提高相聯度可以減少衝突缺失,然後提高相聯度會延長訪問時間,導致整個性能的降低,容量缺失可以簡單地通過增大緩存容量來減少,當然緩存容量增大的同時必然導致訪問時間的增加,也將導致整體性能的降低。

在相聯的緩存中發生缺失時,我們必須決定替換哪一塊,如若是全相聯,那麼所有的塊都是被替換的候選者,如若是組相聯,我們必須在某一組的塊中進行選擇,當然,直接映射的緩存替換很簡單,因為只有一個可以替換的候選者。因此在全相聯或組相聯緩存中 ,有兩種主要的替換策略

隨機法:隨機選擇候選塊,可能使用一些硬件來協助實現,例如TLB缺失、MIPS支持隨機替換

LRU(最近最少使用算法):被替換的塊是最久沒有被使用過的塊 (在大多虛擬存儲器中,對於LRU都是通過提供引用位來近似實現(比如TLB))

指令緩存缺失(數據缺失也類似如此)處理步驟如下:

【1】將程序計數器(PC)的原始值送到寄存器

【2】通知主存執行一次讀操作,並等待主存訪問完成

【3】寫緩存項,將從主存取回的數據寫入緩存中存放數據的部分,並將高位(從ALU中得到)寫入標記域,設置有效位

【4】重啟指令執行第一步,重新取指,這次該指令發生在緩存中

數據訪問是對緩存的控制基本相同:發生缺失時,處理器發生阻塞,直到從存儲器中取回數據后才響應。在執行寫操作時,如果有一個存儲指令,我們只將數據寫入緩存而不改變主存中的內容,那麼在寫入緩存后將導致緩存和主存被認為不一致,保持主存和緩存一致性最簡單的方法是將數據同時寫入主存和緩存中,這種方法稱為【寫直達】法。但是這種方法無法提供良好的性能,因為每次寫操作都要把數據寫入主存中,這些寫操作將花費大量的時間,可能至少花費100個處理時鐘周期,並且大大降低了機器速度,解決這個問題的方案之一是採用【寫緩衝:一個保存等待寫入主存數據的緩衝隊列】,當一個數據在等待寫入緩存時,先將其寫入緩衝中,當數據寫入緩存和緩衝后,處理器可以繼續執行,當寫主存操作完成后,寫緩衝里的數據項也得到有效釋放。如果寫緩衝已經滿了,那麼當處理器執行到一個寫操作時就必須停下來直到寫緩衝中有一個空位置,當然,如果存儲器完成寫操作的速度比處理器產生寫操作的速度慢,那麼再多的緩衝器也無用,因為產生寫操作比存儲系統接收它們更快。

 

除了寫直達方法外,另外一種可選擇的方法是【寫回】,在寫回機制中,當發生寫操作時,新值僅僅被寫入到緩存塊中,只有當修改過的塊被替換時才需要寫到磁盤上,寫回機制可提高系統性能,尤其是當處理器寫操作的速度和主存處理寫操作速度一樣快甚至更快時,但是,寫回機制的實現比寫直達要複雜得多。大部分寫回機制的緩衝也是使用寫緩衝,當在發生缺失替換一個被修改的塊時,寫緩衝可以起到降低缺失代價的作用。在這種情況下,被修改的數據塊移入與緩存相聯的寫回緩衝器,同時從主存中讀出所需要的數據塊。隨後,寫回緩衝器再將數據寫入主存,如果下一次缺失沒有立刻發生,當臟數據塊必須被替換時,這種方法可以減少一半的缺失代價。

總結

一個緩存塊可以放在何處:一個位置(直接映射),一些位置(組相聯),任何位置(全相聯)。

如何找到一個塊:索引(直接映射的緩存中),有限的檢索(組相聯的緩存中),全部檢索(全相聯的緩存中)、專用查找頁表。

緩存缺失時替換哪一塊:隨機選取、LRU

寫操作如何處理:寫直達或寫回策略

本文我們非常詳細的講解了緩存的基本原理,當然對於如何處理緩存一致性並未涉及(大多採用監聽協議),希望通過我對緩存原理的理解能給閱讀的您能有力所能及的幫助,謝謝。 

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

【其他文章推薦】

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

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

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

Spring源碼之自動裝配

引言

我們使用Spring開發過程中經常會用到Autowired註解注入依賴的bean,這部分也是面試的熱點問題之一。今天咱們一起來深入研究下自動注入的背後實現原理。首先上一個例子,如下所示:

@RestController
public class TestController {
    @Autowired
    List<ICheckRuleService> checkRuleService;

    @RequestMapping("/test")
    public void test(){
        checkRuleService.forEach(x->x.valid());
    }
}

從填充Bean開始

Autowired是怎麼實現自動注入的呢,今天我們來通過源碼分析一下。當Spring創建 TestController Bean時,會調用AbstractBeanFactory#doGetBean(如果對Spring創建Bean流程不熟的讀者,可以給我留言,後面考慮是否寫個IOC系列),doGetBean裏面會調用doCreateBean()方法去創建Bean,創建Bean之後,會對Bean進行填充

try {
    this.populateBean(beanName, mbd, instanceWrapper);
    exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}

populateBean 里有這樣一段代碼,看起來是處理Autowired的,分別是autowireByName 和 autowireByType

PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
    MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
    if (mbd.getResolvedAutowireMode() == 1) {
       this.autowireByName(beanName, mbd, bw, newPvs);
    }

   if (mbd.getResolvedAutowireMode() == 2) {
       this.autowireByType(beanName, mbd, bw, newPvs);
   }

    pvs = newPvs;
}

我們來驗證一下,通過斷點調試我們發現並不會進入if里,所以自動注入並不是這裏實現的。那這裡有什麼用呢,先放一放,後面再說。

後置處理器屬性填充

那麼到底是哪裡注入進去的呢?我們繼續往下看,在這段代碼下方有個BeanPostProcessor的邏輯,通過斷點我們發現有個AutowiredAnnotationBeanPostProcessor 的後置處理器,當這個BeanPostProcessor執行完 postProcessPropertyValues方法后,testController的checkRuleService 屬性就有了值了,說明屬性值注入肯定和 AutowiredAnnotationBeanPostProcessor 有關,我們跟進去看一下

進入AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues 方法里,裏面主要有兩部分邏輯

  • 首先看到一段 findAutowiringMetadata 的邏輯,根據方法名稱知道是獲取當前bean的注入元信息

  • 調用 metadata.inject 注入屬性

public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
    InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

    try {
        metadata.inject(bean, beanName, pvs);
        return pvs;
    } catch (BeanCreationException var7) {
        throw var7;
    } catch (Throwable var8) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var8);
    }
}

我們先來看第一部分:findAutowiringMetadata

我們進入findAutowiringMetadata,看下它的邏輯,先從 injectionMetadataCache 緩存里取,如果取不到值,則調用buildAutowiringMetadata 構建 InjectionMetadata ,構建成功後設置到緩存里。

    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
        InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized(this.injectionMetadataCache) {
                metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }

                    metadata = this.buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }

        return metadata;
    }

我們來看下 buildAutowiringMetadata,繼續跟進去,源碼如下:

裏面是通過當前Bean的Class反射獲取 Field 和 Method ,然後對 Field 和 Method 分別調 findAutowiredAnnotation 方法獲取自動注入的註解,然後根據註解類型是否required構建不同類型的InjectedElement。

  • AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement:

boolean required = this.determineRequiredStatus(ann);
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
  • AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement:

boolean required = this.determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));

補充:通過AutowiredAnnotationBeanPostProcessor 構造函數我們知道,自動注入處理的是被 @Autowired 和 @Value 這兩個註解標註的屬性(Field)或方法(Method):

    public AutowiredAnnotationBeanPostProcessor() {

        this.autowiredAnnotationTypes.add(Autowired.class);

        this.autowiredAnnotationTypes.add(Value.class);

    //......

到這裏,需要注入的元數據信息就已經構建完成了,接下來就要到注入部分了。來看下 postProcessPropertyValues 的第二部分。

再看第二部分:metadata.inject

前面獲取到了需要注入的元數據信息,接下來是元數據 inject 的實現,繼續跟進去,裏面是一個for循環,循環調用了element的inject方法

if (!((Collection)elementsToIterate).isEmpty()) {
    for(Iterator var6 = ((Collection)elementsToIterate).iterator(); var6.hasNext(); element.inject(target, beanName, pvs)) {
        element = (InjectionMetadata.InjectedElement)var6.next();
        if (logger.isDebugEnabled()) {
            logger.debug("Processing injected element of bean '" + beanName + "': " + element);
        }
    }
}

我們斷點調試進去,發現element的真實類型是AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement,而當前element 真實類型是 TestController.checkRuleService 的集合。

我們進入AutowiredFieldElement#inject方法,首先嘗試從緩存里拿當前Field的值,肯定拿不到,所以走的是else分支,else分支里從beanFactory里解析當前Field屬性值

value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

繼續跟進去,發現其實調用的 doResolveDependency 方法

越來越接近真相了,不要着急,繼續跟進去

發現一個類型為Object的 multipleBeans ,結果返回的也是這個Object,我們大膽猜測這個Object就是我們需要注入的List屬性,繼續跟進去驗證一下:

我們看一下 Collection 分支的源碼

 else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
            elementType = descriptor.getResolvableType().asCollection().resolveGeneric(new int[0]);
            if (elementType == null) {
                return null;
            } else {
                Map<String, Object> matchingBeans = this.findAutowireCandidates(beanName, elementType, new DefaultListableBeanFactory.MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) {
                    return null;
                } else {
                    if (autowiredBeanNames != null) {
                        autowiredBeanNames.addAll(matchingBeans.keySet());
                    }
​
                    TypeConverter converter = typeConverter != null ? typeConverter : this.getTypeConverter();
                    Object result = converter.convertIfNecessary(matchingBeans.values(), type);
                    if (this.getDependencyComparator() != null && result instanceof List) {
                        ((List)result).sort(this.adaptDependencyComparator(matchingBeans));
                    }
​
                    return result;
                }
            }
        }

裏面是調用了 findAutowireCandidates 來獲取Bean,findAutowireCandidates 內部會獲取到依賴的BeanNames,然後根據beanName 循環調用beanFactory#getBean 獲取需要注入的bean

this.findAutowireCandidates(beanName,elementType,new DefaultListableBeanFactory.MultiElementDescriptor(descriptor))

beanFactory#getBean方法,最終會調用 AbstractBeanFactory#doGetBean,獲取到需要裝配進去的屬性bean。

    public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException {
        return beanFactory.getBean(beanName);
    }

當所有的循環執行完畢,就獲取到了 multipleBeans ,驗證了前面的猜測。真是太不容易,趕緊設置緩存  

最終通過field.set 將獲取到的List屬性值value設置到當前bean里,代碼如下:

if (value != null) {
    ReflectionUtils.makeAccessible(field);
    field.set(bean, value);
}

執行field的set方法后,再來看checkRuleService屬性就有值了

如果是Method注入,對應的就是通過反射調用 method.invoke 將屬性設置到方法參數里,大致流程差不多。到此,Autowired 裝配流程也就結束了。

前面在講到 populateBean 的時候,有個根據 autowireMode 判斷是否執行屬性注入,當時獲取的autowireMode==0,那麼什麼時候autowireMode 會有值並且會根據autowireByName 和 autowireByType來裝配呢?

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)

其實也很好理解,通過源碼我們知道,這裏的 mbd 是一個 RootBeanDefinition ,也就是說這裏的 mbd.getResolvedAutowireMode()獲取的值是通過Bean定義或者通過PostProcessor拿到BeanDefinition,然後設置了AutowireMode屬性才會有值。當我們查看這裏的autowireByType源碼(AbstractAutowireCapableBeanFactory#autowireByType)可以發現,其實autowireByType也是會調用resolveDependency,繼續跟進去,發現其實調用的 doResolveDependency 方法,而AutowiredAnnotationBeanPostProcessor 也是通過這個方法實現的自動注入,後面的流程就都一樣了。

最後總結一下

1、bean創建完成后,會調用 populateBean() 填充Bean,在populateBean()方法里會獲取所有的BeanPostProcessor,並循環執行 BeanPostProcessor#postProcessPropertyValues() 設置屬性

2、其中有個AutowiredAnnotationBeanPostProcessor,這個處理器里會根據當前Bean的Class,通過反射獲取 Field 和 Method ,分別獲取 Field 和 Method 上的自動注入的註解(@Autowired 和 @Value),構建注入元數據InjectionMetadata

3、調用注入元數據InjectionMetadata的 inject() 方法,裝配屬性(有兩種:AutowiredFieldElement 和AutowiredMethodElement),會調用this.beanFactory.resolveDependency(desc,beanName,autowiredBeanNames, typeConverter) 解析依賴的屬性值

4、resolveDependency 最終會調用到 resolveMultipleBeans ,而 resolveMultipleBeans 會根據當前注入屬性的類型分別按 Array、Collection、Map 走不同的分支,在分支里調用 findAutowireCandidates 獲取注入bean的實例,最終回調到 AbstractBeanFactory#doGetBean

5、獲取到所有需要注入的屬性 bean 實例后,通過反射設置到對應的屬性或方法里去,就完成了自動注入全流程了

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

【其他文章推薦】

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

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

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

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

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

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