摘要:一個服務提供器必須包含至少一種方法。服務提供器一旦被注冊,就可被用于程序的各個地方。注意服務提供器的變量來自類中。啟動服務當所有的服務提供器注冊之后,他們就變成了已啟動狀態。再次提示,把服務提供器作為一種組織工具來使用。
聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味的翻譯,能保證90%的原汁性,另外因為是理解翻譯,肯定會有錯誤的地方,歡迎指正。
歡迎轉載,轉載請注明出處,謝謝!
服務提供器 啟動引導Laravel服務提供器是往IoC容器中綁定服務的類。事實上,框架核心就是由很多這樣的服務提供器驅動管理著容器中綁定的各種資源。基本上框架中的所有組件都是以這種使用提供器注入資源到容器的方式進行注冊的。從項目文件app/config/app.php中的providers數組中可以瀏覽到當前項目使用的提供器列表。
一個服務提供器必須包含至少一種方法:register。register方法中實現了類綁定到容器的邏輯。當用戶發起一個請求時,框架啟動,配置文件中定義的服務提供器的register方法會被執行。這在Laravel執行生命周期的早期就會觸發,所以,當你的啟動文件、比如start目錄中的文件加載之后,這些服務啟動器就已經可用了。
注冊 vs 啟動
不要試圖在register方法中使用提供器服務。他只是為了將對象綁定到容器中來使用的。所有關于綁定類的后續操作都應在boot方法中完成的。
一些通過Composer安裝的第三方類庫,都是通過服務提供器進行注入的。類庫的安裝說明會明確的讓你在配置文件中通過向providers數組方法添加配置來使用他們的服務。服務提供器一旦被注冊,就可被用于程序的各個地方。
延遲提供器類庫服務提供
不是所有的類庫都需要服務提供器。實際上,沒有類庫需要它,服務提供器的作用通常被用來啟動組件并使之馬上能被使用。他其實就是一個方便我們啟動引導代碼類庫綁定到容器的工具。
在每次請求中,不是所有的列在providers配置數組中的服務都會被實例化。這對在性能其實是不利的,特別是當他們已經被注冊,但是項目中又沒有使用到它,這就是一種浪費。比如,QueueServiceProvider服務,只有在那些利用了隊列的請求中才會使用到。
為了在請求中,只實例化那些必須的服務,laravel生成了一個“服務器清單”并存儲在app/storage/meta目錄中。清單中列出了所有應用可能需要用到的服務,也記錄了容器需要綁定的類庫的名稱。當應用中需要使用queue服務時,Laravel知道如何從清單中加載并實例化QueueServiceProvider。這種延遲加載服務的方式,極大的提高了整體的性能。
清單的生成
當在providers數組中添加數據時,Laravel會在下一次請求時自動重新生成清單。
有時間的話,還是要好好看看這個清單的,他對你調試延遲加載服務是非常有幫助的。
組織器想使用Laravel構建出一個高擴展性良好的應用,那么就有必要學習并將服務提供器作為一種組織工具來管理我們的代碼。當向IoC容器注入大量類時,代碼都是雜亂的放到app/start文件中來操作的。我們可以使用服務提供器注冊服務的方式來代替上面的方式。
萬物伊始
應用所有“啟動文件”都存放在app/start目錄下的。在請求達到應用時,根據請求類型的不同加載相應的“引導”文件。啟動文件根據當前環境在start.php之后被加載。例如:artisan.php只在終端命令行模式下被加載。
如下示例。我們的應用可能是在使用Pusher4來進行向用戶的消息推送。為了將Pusher進行解耦,這里須要創建一個EventPusherInterface接口和一個PusherEventPuser實現。當需求變更時,我們就能很容易的改變消息服務商。
interface EventPusherInterface{ public function push($message, array $data = array()); } class PusherEventPusher implements EventPusherInterface{ public function __construct(PusherSdk $pusher) { $this->pusher = $pusher; } public function push($message, array $data = array()) { // Push message via the Pusher SDK... } }
下面,我們創建一個EventPuserServiceProvider:
use IlluminateSupportServiceProvider; class EventPusherServiceProvider extends ServiceProvider { public function register() { $this->app->singleton("PusherSdk", function() { return new PusherSdk("app-key", "secret-key"); } $this->app->singleton("EventPusherInterface", "PusherEventPusher"); } }
贊!我們對時間推送進行了清晰的抽象。同時我們還有一個不錯的地方將服務注冊綁定到容器中。我們只須要在app/config/app.php的provider數組中添加EventPusherServiceProvider即可。在接下來的應用中,任何控制器和類都能使用這個注入的服務。
是否須要單例?
我們總需要合適使用bind和singleton。記住一點,一次請求只用一次用singleton,否則用bind。
注意:服務提供器的$app變量來自ServiceProvider類中。他是IlluminateFoundationApplication的實例化對象,繼承自Container類,所以可以上面一樣調用容器中的各種方法。如果你喜歡App這種門面模式,也可以:
App::singleton("EventPusherInterface", "PusherEventPusher");
當然,服務提供器的功能不止于此,我們也可以注冊云存儲、數據庫訪問、自定義模版引擎如Twig等類型的服務。他就是你應用中的引導和管理工具,如此而已。
所以,盡情創建屬于你自己的服務提供器吧。這不需要你非得發布個代碼包,只是個管理管理工具,來方便應用加載各種項目須要的組件。
啟動服務當所有的服務提供器注冊之后,他們就變成了“已啟動”狀態。每個提供器中的boot方法都會觸發。我們通常會犯這樣一種錯誤,就是在register方法試圖去調用其他服務。而此時并不能保證所有的服務均已被加載,服務很可能在當前是不可用的,這就會出現錯誤。因此,我們應該總是在boot方法中去調用其他服務。register方法僅僅是用來將服務注冊到容器中。
在boot方法中,你可以做任何事情:注冊時間監聽器,加載路由文件,注冊過濾器,以及任何你能想到的東西。再次提示,把服務提供器作為一種組織工具來使用。也許你希望把一些監聽事件組織起來?把他們放到boot方法來實現就是一個很好的方法!或者,你也可以引入一個PHP的“事件”或者“路由”文件:
public function boot() { require_once __DIR__."/events.php"; require_once __DIR__."/routes.php"; }
現在我們已經學習了依賴注入和利用服務提供器來組織項目,我們有了使用Laravel創建可維護、可測試程序的應用架構的強大基礎。下面,我們繼續深入學習Laravel本身是如何使用服務提供器,框架如何在這個引擎下工作!
服務核心別被這些框框束縛了自己
記住,不要老想著只有程序包才能使用服務提供器。要將他作為我們組織服務的好工具。
你應該已經注意到app配置文件中已經有很多服務了。每一個都會啟動框架核心的各個部分。比如,MigrationServiceProvider負責加載數據庫遷移的類庫,以及加載Artisan命令;EventServiceProvider負責注冊事件調度類。一些服務相對比較負責,但都是負責啟動框架核心的某一部分。
約一約這些服務們
理解這些核心服務最好的方法還是去讀下源碼。如果能對這些服務的源碼,和容器的注入非常熟悉,那么Laravel的工作原理也就會變的非常明了了。
大部分的服務都是延遲加載的,并非所有請求都會調用他們;然而框架基本的部分像FilesystemServiceProvider和ExceptionServiceProvider還是會隨請求一起啟動的。有些人會說核心服務和容器_就是_Laravel。Laravel就是將所有不同的部分組合成一個單一,內聚的整體。這些服務就是框架這棟大廈的骨架。
再啰嗦一次,想了解Laravel如何工作,還是得看源碼,看看框架如何驅動這些核心服務。能明白這些服務如何組織的一塊,這些服務如何實現本身的功能。深諳這些之后,也許你也能為Laravel做出自己的貢獻!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22951.html
摘要:組件擴展通常有兩種方法向容器中綁定自己的接口實現痛過使用工廠模式實現的類注冊自己的擴展。類庫管理類以工廠模式實現,負責諸如緩存等驅動的實例化。閉包須要傳入繼承自和容器的實例化對象。當完成擴展之后要記住中替換成自己的擴展名稱。 聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味的翻譯,能保證9...
摘要:控制反轉容器控制反轉使依賴注入變得更加便捷。有瑕疵控制反轉容器是實現的控制翻轉容器的一種替代方案。容器的獨立使用即使沒有使用框架,我們仍然可以在項目中使用安裝組件來使用的控制反轉容器。在沒有給定任何信息的情況下,容器是無法實例化相關依賴的。 聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味...
摘要:控制只是用來接收請求并請求邏輯處理類。事實上,業務邏輯無需感知網絡,網絡僅僅接入應用的傳輸機制,他不應超出應用中的路由和控制器的范疇。職責分離是編寫健壯應用的關鍵。其他通常,類庫應該以規范組織在我們的應用中。 聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味的翻譯,能保證90%的原汁性,另...
摘要:劃下重點,服務容器是用于管理類的依賴和執行依賴注入的工具。類的實例化及其依賴的注入,完全由服務容器自動的去完成。 本文首發于 深入剖析 Laravel 服務容器,轉載請注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請求,又是如何生成響應并最終呈現給用戶的工作原理。 本章將帶領大...
摘要:外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。將使用者與子系統從直接耦合,轉變成由外觀類提供統一的接口給使用者使用,以降低客戶端與子系統之間的耦合度。接下來將深入分析外觀服務的加載過程。引導程序將在處理請求是完成引導啟動。 本文首發于 深入淺出 Laravel 的 Facade 外觀系統,轉載請注明出處。 今天我們將學習 Laravel 核心架構中的另一個主題「Fac...
閱讀 1661·2021-10-29 13:11
閱讀 825·2021-09-22 10:02
閱讀 1687·2021-08-20 09:35
閱讀 1548·2019-08-30 15:54
閱讀 2457·2019-08-30 15:44
閱讀 1379·2019-08-29 16:52
閱讀 1098·2019-08-23 12:56
閱讀 749·2019-08-22 15:16