川普開倒車? 各州可自訂碳排標準

摘錄自2018年8月20日自由時報報導

美國總統川普近日將宣布一項新方案,授權各州自行決定如何與是否遏制燃煤發電廠的碳排放,大幅翻轉前朝歐巴馬政府的「潔淨電力計畫」(Clean Power Plan)。然而,根據美國環保署就未來十年溫室氣體排放量的推估,落實川普新措施後的排放量,將是歐巴馬乾淨能源政策的至少12倍。

新計畫將授權各州自行對火力發電廠制定標準較低的法規,還允許各州退出電廠排放法規,將對全美各地許多老舊燃煤發電廠帶來重大影響,恐導致曾一度減少的溫室氣體排放再度升高。

新措施將影響超過300座發電廠,鼓勵業者讓這些火力發電廠繼續運轉,而非以更乾淨的天然氣或再生能源發電取而代之。

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

印度雨季洪災逾410死 超過百萬人流離失所

摘錄自2018年8月21日中央報導

印度官員今天(21日)表示,西南部克勒拉省奪走410多人性命的毀滅性雨季洪災,造成超過100萬人流離失所,湧入各地避難中心棲身。

根據克勒拉省(Kerala)一名議員,約有5萬棟民宅遭摧毀,民眾紛紛湧入避難中心,而洪水消退顯露出破壞的規模。軍隊表示,城鎮上有數千人仍待淹水的住家中,10天傾盆大雨已重創克勒拉省。

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

※FB行銷專家,教你從零開始的技巧

攻電動自行車商機,宏碁旗下聯永基推新電池模組搶市

根據研究機構指出,近幾年電動自行車銷售量在世界多國都呈雙位數成長,看好全球電動自行車市場需求,宏碁旗下聯永基以自身專業電池管理技術結合母公司宏碁在智慧裝置領域的優勢,推出強化安全及智慧的電動自行車電池模組;聯永基表示,此款專為電動自行車打造的電池模組共有三種型式,可依照客戶及車廠需求安裝於後車架、下管隱藏及斜管,而該電池模組也已領先業界通過 ISO 13849 功能安全規範,更已符合歐盟最新的 EN 15194:2017 電動自行車標準 。

聯永基總經理張瑞川表示,隨著科技的發展,日常生活中的各種產品逐漸電子化,電池安全在這之中為共通的關鍵議題之一,身為專業電池模組開發商,公司有責任將安全視為產品開發的最高準則,帶給使用者安心的使用體驗,此電池模組不僅領先同業取得 ISO 安全規範,更具備設計符合使用者需求的智慧 APP 即時掌握電池狀態並記錄騎乘資訊,而近年電動輕型載具市場在全球快速成長,除了電動自行車外,電動滑板等載具也相繼應運而生,針對長者與行動不便人士打造的電動輔具也日益普及。

為達最高規格的安全標準,聯永基表示,公司為台灣率先獲 ISO 13849 功能安全規範的電動自行車電池模組廠商,針對電動自行車成長率極高的歐洲市場,前述 ISO 認證為獲歐盟 EN 15194:2017 電動自行車安全標準的必要條件;此外,公司電動自行車電池模組獲得國內 CNS 15387 認證,是一款台灣在地生產組裝的電池模組產品,不但符合國際安規,更具多重安全系統,對於異常電壓、電流、溫度皆有保護機制,電池模組設計具有較佳的抗潑水及防塵設計。

聯永基指出,獨特的智慧通訊模組讓使用者能藉由手機 APP 即時掌握電池狀況,包含電池容量、電壓、充電時間、保固時間等,還可鎖定電池,並在故障時顯示對應故障碼,方便使用者釐清故障原因;另外,提供智慧車錶功能,可記錄車速、位置、騎乘時間等,APP 也可因應各種不同客戶需求,提供使用、租用、共享的多元系統整合服務。

聯永基亦指出,公司可配合客戶對產品外觀及功能上的不同要求,打造客製化電池模組、提供多種電池芯容量選擇,且因台灣具備完整自行車生態鏈,公司可快速與上下游合作提供對應的解決方案,迅速結合在地組車廠及其他供應鏈進行產品開發測試,節省運輸時間與成本,彈性地根據客戶需求打造理想產品。

(本文內容由 授權使用。首圖來源:)

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

【其他文章推薦】

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

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

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

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

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

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

橡樹嶺國家實驗室發表 120 千瓦電動車無線充電系統

手機無線充電越來越普及,那麼未來電動車是不是也能無線充電?美國能源部隸屬的橡樹嶺國家實驗室多年來一直都在研發車用無線充電技術,如今更進一步,功率從 2 年前的 20 千瓦(kilowatt)提升到 120 千瓦,無線充電速度可比擬特斯拉(Tesla)的超級充電樁,可說車用無線充電離商用化實現又更進一步。

橡樹嶺國家實驗室前次發表車用無線充電研究成果是在 2016 年 3 月底,研究合作夥伴包括豐田、思科(Cisco)、大功率無線充電設備商 Evatran,以及美國南卡羅萊納州克萊門森大學的國際汽車研究中心,當時發表的原型的充電功率為 20 千瓦,充電轉換效率為 90%。

時隔 2 年多之後,2018 年 10 月,橡樹嶺國家實驗室發表最新研發成果,功率提升到 120 千瓦,充電效率提升到 97%,與當前有線快速充電裝置相當,研發過程採用電腦模擬,在線圈設計等各方面同時最佳化,為了達到 120 千瓦大功率,同時又不至於大幅增加系統設備體積重量,採用最新的碳化矽電子元件。

無線充電系統的結構是由電網取得電力,轉換為高頻率的交流電,通過線圈產生磁場,磁場變化使得 6 英吋距離外的車上充電線圈產生交流電力,在經由整流器轉為直流電,供電給車子的電池組儲存。橡樹嶺國家實驗室目前的裝置是向車子充電,未來將研發可雙向的裝置,也就是不但可以電網對電動車充電,必要時也能電網從電動車汲取電力,使得所有的電動車都能成為電網的能源儲存資源。

橡樹嶺國家實驗室成功打造 120 千瓦的原型,使得能源部提出更大膽的目標:發展 350~400 千瓦的充電裝置,能在 15 分鐘內充飽汽車電池,因應這個新目標,橡樹嶺國家實驗室下一步將發展 200 千瓦的裝置,最後往 350 千瓦邁進,並強化動態充電技術,所謂動態充電,就是電動車不是停在無線充電裝置上充電,而是例如整段馬路都有無線充電功能,電動車可一面行駛一面充電,目前相關技術都還太過複雜昂貴,橡樹嶺國家實驗室希望能打造可以在高速公路行駛速度下還能充電的動態充電系統。

橡樹嶺國家實驗室目前正與可能的合作代工廠討論未來的商用生產,同時,民間也還有其他競爭者,車用無線充電新創公司 Hevo 已經在進行從原型進入量產的階段,計畫生產數千具產品,未來 18 個月內供應簽約的電力公司和車廠;麻州車用無線充電公司 WiTricity 則於 2018 年 10 月與安潔無線科技簽下授權合約,安潔無線將供應無線充電產品給中國車廠,WiTricity 的 Drive 11 充電技術,充電功率為 11 千瓦,充電效率為 93%。

即使動態充電還是遙遠的夢想,但對市區交通來說,只要路口的馬路下都裝有靜態的無線充電裝置,等待紅綠燈時,就能自然充電,如此一來,電動車將可以整天行駛,永遠不用擔心電力耗盡,也不需到充電樁充電,比起終將需要去加油站加油的內燃機汽車還更方便,甚至車廠可因此推出電池容量較小的版本,而能大為減低成本,如此一來,將可革命性的推動電動車的發展。

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

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

【其他文章推薦】

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

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

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

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

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

中國氫能產業發展迅速,氫燃料電池車突破 2 千輛

中國媒體報導,中國張家口氫能與可再生能源論壇日前召開,根據論壇公布數據顯示,中國在氫能與燃料電池汽車產業方面快速發展,目前已有 2,000 多輛氫燃料電池汽車。

張家口利用自身豐富的風電、光伏可再生能源優勢,藉助 2022 年冬季奧運會由北京舉辦的東風,正大力發展氫能產業。據規劃,到 2020 年張家口市投入使用的燃料電池公交車、物流車、出租車將達到 1,800 輛,建成加氫站 21 座,實現製氫年產 2 萬噸、燃料電池發動機產能 1 萬台、燃料電池客車年產 4,500 輛,初步形成從氫氣製備、儲運、加註到燃料電池發動機和整車研發、生產、檢測的全產業鏈。

另外,自 2016 年以來,中國在氫能與燃料電池汽車產業方面獲得快速發展,形成京津冀、華東、華南、西南、華中、西北、東北等氫能與燃料電池汽車產業集群,建立起相對成熟的產業配套和商業化應用體系。

數據顯示,中國現在已經有 2,000 多輛氫燃料電池汽車和 12 座加氫站。目前,北美、歐洲、日本和韓國的燃料電池汽車產業已進入商業化階段,惟中國仍處於商業化初期。

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

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

【其他文章推薦】

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

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

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

※超省錢租車方案

※FB行銷專家,教你從零開始的技巧

第九屆中國國際新能源暨智慧汽車論壇 2019

2019 年 4 月 2-3 日∣中國·上海

新能源時代,攜手智慧化未來

2019 年是實施「十三五」規劃的重要一年,《中共中央關於制定國民經濟和社會發展第十三個五年規劃的建議》把新能源汽車推廣列入國家的重要計畫之中,要求提高電動汽車產業化水準。這表明在「十三五」期間,新能源汽車發展在整個國民經濟和社會發展中將處在十分重要的地位,明確了新能源汽車在國民經濟和社會發展中的戰略定位。「十三五」期間,中國將成為世界最大的新能源汽車市場,成為世界新能源汽車的核心主戰場。

在過去八屆新能源汽車論壇成功舉辦的基礎上,由希邁商務諮詢(上海)有限公司主辦的第九屆中國國際新能源暨智慧汽車論壇 2019 即將於 4 月 2 日- 4 月 3 日在上海隆重舉行。新能源汽車系列論壇成功邀請了包括國家發改委能源研究所、世界電動車協會、亞太電動車協會、世界氫能協會、世界分散式能源聯盟、中國工程院等在內的政府單位與研究機構,以及包括 BMW、賓士、奇瑞捷豹路虎、Volkswagen、奧迪、比亞迪、上汽、北汽,大陸,電裝,LG 等在內的知名整車商及綜合零部件商,共同研討新能源汽車產業政策趨勢、技術路線及難點、基礎設施建設、商業模式等並取得了豐碩的成果,獲得了業內外人士的一致好評。

在即將到來的 2019 年,組委會為感謝業內外人士對系列論壇長期以來的支援和關注,將傾情奉上相比歷屆舉辦規模最大的第九屆新能源汽車論壇,涉及 8 個論壇,CEO TALK,頒獎典禮,一對一洽談及雞尾酒會。屆時將誠邀全球範圍內的整車製造商、動力總成公司、動力電池及燃料電池廠商、充電、儲能企業、零部件供應商、核心技術服務提供者和政府官員等近 900 位產業人士一起,對新能源汽車產業面臨的挑戰,機遇與對策各方面進行為期 2 天更深層次並具有建設和戰略性的探討。

會議亮點

Ø  豐富的內容:

8 大板塊的深度解析

Ø  參會嘉賓:

900+ 高度滿意的企業決策者,200+ 業內知名企業,30+ 國家和地區

Ø  參會嘉賓分析:

17%+ 來自各國政府部門及權威機構,25%+ 來自知名整車商

Ø  演講嘉賓:

70+ 世界新能源汽車產業知名發言嘉賓

Ø  交流機會:

16+ 小時的交流機會:圓桌討論、VIP 午宴和開放式問答

Ø  會議形式:

8 個論壇,1 場雞尾酒晚宴 + 一對一洽談,1 個頒獎典禮,1 個 CEO Talk

 

會議結構

若您對活動有更多要求,請撥打 021-6045 6030 與我們聯繫,謝謝理解和支持!

我們期待與貴單位一起出席於 2019 年 4 月 2 日– 3 日在上海舉辦的第九屆中國國際新能源暨智慧汽車論壇, 以利決策!

 

欲知更多會議詳情,請登陸官方網站:

連絡人:Latika LIU(劉小姐)

電話:021-6045 6030

傳真:021-6047 5887

郵箱:

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

【其他文章推薦】

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

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

※超省錢租車方案

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

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

福斯將在美國闢新廠,生產電動車

新版北美自貿協定(NAFTA)再發威!福斯(Volkswagen)揮軍電動車,為了卡位美國市場,打算在美國設立新廠,目前正在尋找合適地點。

路透社報導,福斯 11 月稍早宣布,2023 年前將斥資近 440 億歐元(約 500 億美元)發展電動車、自動駕駛、新移動服務,並探詢和美國車廠福特汽車合作的可能性。福斯計劃 2020 年發售電動車,為了達成此一目標,該公司將先在海外生產,之後改到美國新廠製造。

新上任的福斯美國區執行長 Scott Keogh 28 日表示,福斯 2020 年將推出售價 3 萬至 4 萬美元的電動車,為此需要新的工廠。福斯在美國田納西州已有工廠,生產 Passat 和 Atlas 等車款,田納西廠仍有足夠空間,是新廠可能的落腳地點之一,但是不必然在此設廠。

(本文內容由 授權使用。首圖來源:)

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

哈雷機車大轉型,推出電動機車

說起哈雷機車(HARLEY-DAVIDSON),大部分人心中就響起重機隆隆的引擎聲,這註冊商標般的引擎聲,讓哈雷機車得到猛豬(hog)美譽,形象深植人心到,哈雷連股票交易代碼都用「HOG」代表自己。轟轟隆的哈雷機車引擎聲,是男人的浪漫,然而,不可想像的事情發生了,哈雷機車竟然推出電動機車,電動化也就代表沒有引擎而是以馬達取代,當然就不會有轟隆隆的引擎聲,這樣真的可以嗎?

2018 年 11 月 6~12 日舉辦的米蘭國際機車暨零件展(EICMA),哈雷發表 LiveWire 電動機車,跨出這個讓世人震驚的重大一步。哈雷機車必須全力轉型,吸引全新世代的新消費者,推出電動機車、油電混合機車,是其中不可或缺的一步,即使這代表向過去告別,也在所不惜。

哈雷機車為何做出如此甘冒大不韙的決策,根本原因是:人口學。傳統重機車的消費者年年變老,但是新近世代的年輕消費者卻未加入,這使重機車市場消費者呈現老化結構,美國幾乎半數重機車消費者都已經年過 50,他們或許還老當益壯,但是隨著年紀再更大,會因退休而無法一直購買新車,也會因體力衰老終於不方便騎車,最老的一代更會來到人類壽命的終點。

哈雷機車未雨綢繆,雖然 2018 年第三季季報仍然超越市場預期,但市佔率已開始萎縮,隨著忠實消費族群一年年老化,新消費者再不加入,哈雷遲早要被時代淘汰。因此 2017 年,哈雷訂下了 10 年計畫,預定到 2027 年要吸引 200 萬新車主,包括大力進軍電動機車,甚至輕型機車、電動腳踏車。另一方面,許多新世代只想輕鬆騎車,覺得重機危險麻煩又辛苦,為了打破這種刻板印象,哈雷打算設立許多學校,教導新世代怎麼騎機車。

電動機車其實相對於內燃機機車有許多技術優勢,例如不需換檔,且從靜止開始的加速扭力相對極大,加速過程沒有換檔的中斷時間,更無比順暢。以電動車為例,特斯拉(Tesla)Model S P100D 從靜止加速到時速 60 英哩只要 2.5 秒。這種超快加速力,很適合喜愛機車遠比汽車加速度更快的機車玩家。但很顯然的,電動機車不會有引擎聲,取而代之的是電動傳動系統的馬達聲。

哈雷機車計畫在未來幾年推出數款新機車產品線,LiveWire 是其中之一,預定於 2019 年底,於美國與歐洲精選通路上市,2019 年初就會公布售價。不過,哈雷機車轉型到電動機車之路,還有許多困難,內燃機與電動傳動系統是完全不同的專業領域,哈雷能否專精是一大問題,即使挑戰成功,還有競爭對手的障礙,成立於 2006 年的加州電動機車廠 Zero Motorcycles 已推出 4 款電動機車,還預定 2019 年 10 月發表電動機車新產品線。

無論如何,在老車主逐漸老化凋零的不可逆潮流下,哈雷機車這個響噹噹的品牌,能否繼續存續,還是得看電動化能不能成功了。

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

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

※FB行銷專家,教你從零開始的技巧

【Spring】Bean的LifeCycle(生命周期)

菜瓜:水稻,上次說Bean的LifeCycle,還沒講完

水稻:啥?說人話?

菜瓜:spring,bean,生命周期

水稻:。。。那你真的是很棒棒哦!。。。bean生命周期的話,從BeanFactory、ApplicationContext和FactoryBean開始說起

  • 我們知道(你不一定知道)BeanFactory是Spring訪問Bean容器的根接口,源碼的註釋: “The root interface for accessing a Spring bean container.”
  • 而ApplicationContext繼承自BeanFactory,也就是說它具有BeanFactory的屬性和方法,並進一步完善(繼承其他的接口)
  • FactoryBean跟前兩個關係就不怎麼大了,它是spring提供給用戶創建bean的口子,有一些bean創建過程複雜,或者依賴第三方包等(Mybatis-Spring中),可交給用戶自己創建

菜瓜:嗯。。陷入沉思。。(欲言又止)

水稻:講理論不給代碼就是耍流氓

  • package com.vip.qc.postprocessor;
    
    import org.springframework.beans.factory.FactoryBean;
    import org.springframework.stereotype.Component;
    
    /**
     * @author QuCheng on 2020/6/15.
     */
    @Component("fb")
    public class FactoryBeanT implements FactoryBean<FactoryBeanT.CustomBean> {
    
        public FactoryBeanT() {
            System.out.println("實現FactoryBean接口的類自身被放在IOC一級緩存的容器裏面,getObject的對象是在另一個緩存對象中");
        }
    
        @Override
        public CustomBean getObject() {
            return new CustomBean();
        }
    
        @Override
        public Class<?> getObjectType() {
            return CustomBean.class;
        }
    
        static class CustomBean {
            public CustomBean() {
                System.out.println("自定義bean");
            }
        }
    }
    
    測試方法
    @Test
    public void testTransa() {
        BeanFactory context = new AnnotationConfigApplicationContext(ComponentScanD.class);
        System.out.println("factoryBean : " + context.getBean("fb"));
        System.out.println("&factoryBean : " + context.getBean("&fb"));
    }

    測試結果

      實現FactoryBean接口的類自身被放在IOC一級緩存的容器裏面,getObject的對象是在另一個緩存對象中
      自定義bean
      factoryBean : com.vip.qc.postprocessor.FactoryBeanT$CustomBean@214b199c
      &factoryBean : com.vip.qc.postprocessor.FactoryBeanT@20d3d15a

菜瓜:懂了,BeanFactory是Spring的核心–容器,ApplicationContext則是包裹容器的上下文,豐富容器的功能(資源加載,事件驅動等)。FactoryBean也是Spring擴展性的提現

水稻:WC,你這個總結提到了精髓。就是擴展性:如果BeanFactory是核心思想,那麼其他的上下文,後置處理器,還是Aware接口等等,都是為了實現擴展

菜瓜:鋪墊說完了,開始生命周期唄

水稻:這次咱們反過來先看源碼,再看實驗,再總結

  • BeanFactory源碼註釋 – 定義了實現的生命周期
  •  * @author Rod Johnson
     * @author Juergen Hoeller
     * @author Chris Beams
     * @since 13 April 2001
     * @see BeanNameAware#setBeanName
     * @see BeanClassLoaderAware#setBeanClassLoader
     * @see BeanFactoryAware#setBeanFactory
     * @see org.springframework.context.ResourceLoaderAware#setResourceLoader
     * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
     * @see org.springframework.context.MessageSourceAware#setMessageSource
     * @see org.springframework.context.ApplicationContextAware#setApplicationContext
     * @see org.springframework.web.context.ServletContextAware#setServletContext
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
     * @see InitializingBean#afterPropertiesSet
     * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
     * @see DisposableBean#destroy
     * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
     */
    public interface BeanFactory {
  • BeanFactory源碼實現類
  • public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory
    
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                // BeanNameAware BeanFactoryAware ...
                invokeAwareMethods(beanName, bean);
            }
    
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                // BeanPostProcessor Before  @PostConstruct
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                // initMethod InitializingBean接口
                invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        (mbd != null ? mbd.getResourceDescription() : null),
                        beanName, "Invocation of init method failed", ex);
            }
            if (mbd == null || !mbd.isSynthetic()) {
                // BeanPostProcessor after
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
    
            return wrappedBean;
        }
  • 實驗代碼
  • package com.vip.qc.postprocessor;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * @author QuCheng on 2020/6/14.
     */
    @Component
    public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor {
    
        public static final String BEAN_NAME = "initializingBeanT";
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_NAME);
            System.out.println("BeanFactoryPostProcessor bean " + initializingBeanT.getBeanClassName());
        }
    }
    
    
    
    package com.vip.qc.postprocessor;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
    /**
     * @author QuCheng on 2020/6/14.
     */
    @Component
    public class BeanPostProcessorT implements BeanPostProcessor {
    
        public static final String BEAN_NAMET = "initializingBeanT";
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (BEAN_NAMET.equals(beanName)) {
                InitializingBeanT processorT = ((InitializingBeanT) bean);
                System.out.println("BeanPostProcessor BeforeInitialization " + processorT);
            }
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (BEAN_NAMET.equals(beanName)){
                InitializingBeanT processorT = ((InitializingBeanT) bean);
                System.out.println("BeanPostProcessor AfterInitialization " + processorT);
            }
            return bean;
        }
    
    }
    
    
    package com.vip.qc.postprocessor;
    
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    /**
     * @author QuCheng on 2020/6/14.
     */
    @Component
    public class InitializingBeanT implements BeanNameAware, InitializingBean, DisposableBean {
    
        public InitializingBeanT() {
            System.out.println("init無參構造 execute");
        }
    
        @PostConstruct
        public void postConstruct() {
            System.out.println("@PostConstruct  execute");
        }
    
        @PreDestroy
        public void preDestroy() {
            System.out.println("@PreDestroy  execute");
        }
    
        @Override
        public void afterPropertiesSet() {
            System.out.println("InitializingBean afterPropertiesSet --> " + this.toString());
        }
    
        @Override
        public void setBeanName(String name) {
            System.out.println("BeanNameAware : " + name);
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
        }
    }
    
    
    測試代碼
        @Test
        public void testLifeCycle() {
            AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ComponentScanD.class);
            applicationContext.close();// 這裏不關閉容器的話,註銷bean的方法會看不到打印
        }

    測試結果

      BeanFactoryPostProcessor bean com.vip.qc.postprocessor.InitializingBeanT
      init無參構造 execute
      BeanNameAware : initializingBeanT
      BeanPostProcessor BeforeInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
      @PostConstruct execute
      InitializingBean afterPropertiesSet –> com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
      BeanPostProcessor AfterInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
      @PreDestroy execute
      destroy

菜瓜:實現什麼的不重要,接口才是爸爸呀,BeanFactory定義好了生命周期,下面的實現也只是實現罷了

水稻:哈哈,你說的對,一流的公司賣標準

菜瓜:這裏怎麼沒看到循環依賴的處理啊

水稻:是的。這裏的源碼我只截取了bean初始化完成之後的接口調用。循環依賴的處理在它前面。來來來,繼續剛

菜瓜:剛不了剛不了,你一下子搞這麼多玩意給我看,我哪看得完

水稻:您歇着,下次您什麼時候想了解我再給您說

 

總結

  • BeanFactory已經定義了整個的生命周期,子類只是負責實現,demo演示也只是為了證實。我們更應該關注更上層的東西 
  • ApplicationContext是對容器更精細化的包裝,提供了更完善的功能
  • FactoryBean是Spring擴展性的提現,可供用戶自己定義創建bean。擴展性提煉的很好

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

【其他文章推薦】

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

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

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

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

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

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

node實現文件屬性批量修改(時間屬性)

前言

在默認情況下,一個文件的創建時間和修改時間是系統自己設定的,我們不能修改該的。但我們有時為了某種特殊需要,為了不讓別人一眼看出文件已經給修改了,我們又需要修改文件的創建時間和修改時間。那麼如何修改文件夾時間,如何修改文件的創建時間,如何批量修改文件的創建時間、修改時間和訪問時間呢?別著急,接下來就帶你自己修改他們。所以,閑話不多說啦,開始寫我們的代碼啦~~

ps:小工具推薦NewFileTime,以上簡述摘抄於NewFileTime

簡單的搭建一下

  • 新建一個 files 目錄

  • 初始化一個node項目工程

    npm init -y
    

看到這裏你會發現,其實我沒有安裝依賴,是因為原生的庫有這個自帶的功能嗎?說是也行,說不是也行。原生的utimes目前支持修改文件的修改時間和訪問時間,不支持修改文件的創建時間,所以我們需要藉助一個第三方庫來修改。

為什麼不直接安裝這個第三方庫呢?

因為這個庫有些許特殊,分兩種情況,一個是低版本Node可以直接安裝,在我本機的Node13上運行則會失敗。具體原因嘛,可以看看下方的鏈接

ps: 原因 + 解決方案

所以,在低版本的Node我們可以直接npm install @ronomon/utimes,而在版本相對較高的則需要npm i https://github.com/Jule-/utimes.git#napi-migration啦

這裏也提一嘴,如果@ronomon/utimes安裝失敗的話,是因為這些原生Node拓展是需要編譯的,所以我們可能需要安裝windows-build-tools,即以管理員身份啟動PowerShell並運行:

npm install --global windows-build-tools

安裝完依賴之後就可以正式寫我們的代碼啦,其實這個代碼相對簡單,就是直接調用它的api就好了。

簡單的使用一下

  • 新建一個test-files文件夾

  • 在test-files文件夾新建1.txt文件供我們測試

  • 編寫如下代碼:

    // 導入 utimes
    const { utimes } = require("@ronomon/utimes");
    utimes(
      "./test-files/1.txt",
      // 創建時間
      +new Date("2010/01/01"),
      // 修改時間
      +new Date("2010/01/02"),
      // 訪問時間
      +new Date("2010/01/03"),
      (err) => {
        //  修改成功的回調
        console.log(`success`);
      }
    );
    
  • 運行代碼,node app.js,是都發現日期發生了改變呢?

看到這裏你以為是不是寫完了,其實也差不多了 ,不過我當然不會讓你收穫這麼少的,至少我們可以看看我們這個最最最簡單的例子的缺點,比如代碼沒有Promise化,那麼我們就封裝一下utimes

/**
 *
 * @param {String} path => 路徑
 * @param {Number} btime => 創建時間,不傳即不修改
 * @param {Number} mtime => 修改時間,不傳即不修改
 * @param {Number} atime => 訪問時間,不傳即不修改
 */
const utimesPromise = (path, btime, mtime, atime) => {
  return new Promise((resolve, reject) => {
    utimes(path, btime, mtime, atime, (err) => (err ? reject(err) : resolve()));
  });
};

當然- -,因為我們使用的是Node,所以我們不需要常規的用new Promise封裝,可以直接使用內置的util這個工具中的promisify方法封裝即可

util.promisify 是在 node.js 8.x 版本中新增的一個工具,用於將老式的 Error first callback 轉換為 Promise 對象,讓老項目改造變得更為輕鬆。在官方推出這個工具之前,民間已經有很多類似的工具了,比如 es6-promisify、thenify、bluebird.promisify。以及很多其他優秀的工具,都是實現了這樣的功能,幫助我們在處理老項目的時候,不必費神將各種代碼使用 Promise 再重新實現一遍。

所以,我們的封裝又變得更加簡單了,代碼如下:

const { promisify } = require("util");
const utimesPromise = promisify(utimes);

之前的代碼就可以改寫成之前我們那樣的自執行Async Function了,代碼如下:

// ...
(async () => {
  await utimesPromise(
    "./test-files/1.txt",
    // 創建事件
    +new Date("2010/01/01"),
    // 修改時間
    +new Date("2010/01/02"),
    // 訪問時間
    +new Date("2010/01/03")
  );
})();

寫到這裏,你會發現其實我們根本沒有做批量修改,是因為有了之前的經驗,我們可以直接通過glob這個工具獲取所有的路徑,根本不要我們操心,寫起來也十分簡單,所以我打算最後再來寫

  • 安裝glob

    npm i glob -S
    
  • 多建幾個文件用於測試我們的代碼

    得出下面列表:

  • 修改我們的代碼:

    const { utimes } = require("@ronomon/utimes");
    const glob = require("glob");
    const { promisify } = require("util");
    
    /**
     *
     * @param {String} path => 路徑
     * @param {Number} btime => 創建時間,不傳即不修改
     * @param {Number} mtime => 修改時間,不傳即不修改
     * @param {Number} atime => 訪問時間,不傳即不修改
     */
    const utimesPromise = promisify(utimes);
    
    (async () => {
      const paths = glob.sync("./test-files/**");
      const len = paths.length;
      for (let i = 0; i < len; i++) {
        await utimesPromise(
          paths[i],
          +new Date("2010/01/01"),
          +new Date("2010/01/02"),
          +new Date("2010/01/04")
        );
      }
    })();
    
  • 得出結果

這樣子就遞歸了我們所有的文件夾跟子文件了進行修改了,本來想着在加載名字修改的,但苦於- -沒有界面,篇幅也過長,就留着過幾天再寫了。

gitee 地址,github 地址

最後

感謝各位觀眾老爺的觀看 O(∩_∩)O 希望你能有所收穫

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

【其他文章推薦】

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

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

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

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

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