摘要:因?qū)嶋H項(xiàng)目需求,近日在開發(fā)包的時(shí)候,發(fā)現(xiàn)設(shè)置屬性設(shè)置為時(shí),會(huì)導(dǎo)致在方法中注冊的無效。研究源碼在中注冊無效,但是在其他中注冊有效,說明是其他問題。所以切記如果準(zhǔn)備采用延遲加載時(shí),嚴(yán)禁進(jìn)行注冊等系列操作。嚴(yán)禁在延遲加載的注冊和。
因?qū)嶋H項(xiàng)目需求,近日在開發(fā) laravel-database-logger 包的時(shí)候,發(fā)現(xiàn)設(shè)置 ServiceProvider defer 屬性設(shè)置為 true 時(shí),會(huì)導(dǎo)致在 register 方法中注冊的 middleware 無效。
class ServiceProvider extends IlluminateSupportServiceProvider { protected $defer = true; public function register() { $this->mergeConfigFrom( __DIR__ . "/../config/config.php", "ibrand.dblogger" ); $this->app->singleton(DbLogger::class, function ($app) { return new DbLogger(); }); //當(dāng) $defer 設(shè)置為 true 時(shí),在路由中引用 databaselogger middleware 會(huì)報(bào)錯(cuò),提示 databaselogger class not found. $this->app[IlluminateRoutingRouter::class]->middleware("databaselogger", Middleware::class); } public function provides() { return [DbLogger::class]; } }
當(dāng)問題出現(xiàn)的時(shí)候就懷疑是因?yàn)樵O(shè)置了 defer 屬性設(shè)置為 true 導(dǎo)致的,立刻就修改源碼把 protected $defer = true; 的代碼注釋掉,結(jié)果仍然是提示 databaselogger class not found.,說明 Laravel 并沒有注冊此 ServiceProvder
接下來就是想如何解決此問題,嘗試了下面的方法:
1. 驗(yàn)證本身代碼是否存在問題
在正常注冊的 AppServiceProvider 中注冊自己的 ServiceProvider
public function register() { // $this->app->register(IbrandDatabaseLoggerServiceProvider::class); }
注冊后結(jié)果一切正常。
2. 研究源碼
在 config/app.php 中 providers 注冊無效,但是在其他 ServiceProvider 中注冊有效,說明是其他問題。
通過研究 IlluminateFoundationApplication 源碼找到 registerConfiguredProviders 方法:
Laravel 是在此方法中去讀取 config/app.php 中的 providers 內(nèi)容并load到 ProviderRepository 中。
(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath())) ->load($providers->collapse()->toArray());
重點(diǎn)在 $this->getCachedServicesPath() ,通過源碼發(fā)現(xiàn) Laravel 是根據(jù) bootstrap/cache/services.php 文件去決定如何注冊 ServiceProvider。
此時(shí)想到了為什么之前注釋了 //protected $defer = true; 代碼后仍然無效的原因。
所以為了讓注釋后的 //protected $defer = true; 代碼有效需要執(zhí)行
php artisan clear-compiled php artisan optimize
之后問題就解決了,也更加深入理解了 ServiceProvider 的原理。
所以切記:如果準(zhǔn)備采用延遲加載ServiceProvider時(shí),嚴(yán)禁進(jìn)行注冊 middleware, route 等系列操作。同時(shí),更改 defer 屬性值后,需要執(zhí)行 php artisan clear-compiled 和 php artisan optimize 以更新 ServiceProvider 緩存。
3. 為什么 AppServiceProvider 中注冊有效?
愿意很簡單,因?yàn)?AppServiceProvider 并沒有延遲加載,因此在執(zhí)行 AppServiceProvider 中 register 方法去注冊新的 ServiceProvider 也是不會(huì)延遲加載的。
總結(jié)謹(jǐn)慎使用延遲加載 ServiceProvider
更改 defer 屬性值后,需要執(zhí)行 php artisan clear-compiled 和 php artisan optimize 以更新 ServiceProvider 緩存。
嚴(yán)禁在延遲加載的 ServiceProvider 注冊 middleware 和 route 。
討論交流文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/26285.html
摘要:調(diào)用了的可以看出,所有服務(wù)提供器都在配置文件文件的數(shù)組中。啟動(dòng)的啟動(dòng)由類負(fù)責(zé)引導(dǎo)應(yīng)用的屬性中記錄的所有服務(wù)提供器,就是依次調(diào)用這些服務(wù)提供器的方法,引導(dǎo)完成后就代表應(yīng)用正式啟動(dòng)了,可以開始處理請求了。 服務(wù)提供器是所有 Laravel 應(yīng)用程序引導(dǎo)中心。你的應(yīng)用程序自定義的服務(wù)、第三方資源包提供的服務(wù)以及 Laravel 的所有核心服務(wù)都是通過服務(wù)提供器進(jìn)行注冊(register)和引...
摘要:總結(jié)本文主要學(xué)習(xí)了啟動(dòng)時(shí)做的七步準(zhǔn)備工作環(huán)境檢測配置加載日志配置異常處理注冊注冊啟動(dòng)。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動(dòng)Bootstrap工作,本文主要學(xué)習(xí)相關(guān)源碼,看看Laravel啟動(dòng)程序做了哪些具體工作,并將個(gè)人的研究心得分享出來,希望對別人有所幫助。Laravel在入口index...
摘要:實(shí)例化各服務(wù)提供者,根據(jù)其屬性將服務(wù)進(jìn)行分類延遲服務(wù)即時(shí)服務(wù),從而得到一個(gè)數(shù)組格式如,延遲處理注冊延遲的服務(wù),以后再進(jìn)行調(diào)用注冊延遲的事件即時(shí)處理直接進(jìn)行注冊調(diào)用等,并重新寫入到,然后根據(jù)此文件進(jìn)行相應(yīng)的處理。 Laravel Kernel引導(dǎo)流程分析 代碼展示 protected function sendRequestThroughRouter($request) { # ...
摘要:大家都知道項(xiàng)目寫起來是挺爽,但是在生產(chǎn)環(huán)境性能不高,我們來抽絲剝繭分析我自己項(xiàng)目的運(yùn)行時(shí)間消耗耗時(shí)步驟耗時(shí)觀察初步結(jié)論在調(diào)用和的方法時(shí),消耗時(shí)間是大頭。類是用于注冊服務(wù)提供者的。但此優(yōu)化在下無效。我們進(jìn)一步分析。 大家都知道 laravel 項(xiàng)目寫起來是挺爽,但是在生產(chǎn)環(huán)境性能不高,我們來抽絲剝繭分析我自己項(xiàng)目的運(yùn)行時(shí)間消耗: Bootstrap 耗時(shí) 步驟 耗時(shí) Illum...
摘要:說明本文主要學(xué)習(xí)容器的實(shí)例化過程,主要包括等四個(gè)過程??聪碌脑创a如果是數(shù)組,抽取別名并且注冊到中,上文已經(jīng)討論實(shí)際上就是的。 說明:本文主要學(xué)習(xí)Laravel容器的實(shí)例化過程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...
閱讀 3051·2021-11-16 11:45
閱讀 5419·2021-09-22 10:57
閱讀 1824·2021-09-08 09:36
閱讀 1697·2021-09-02 15:40
閱讀 2563·2021-07-26 23:38
閱讀 1302·2019-08-30 15:55
閱讀 990·2019-08-30 15:54
閱讀 1275·2019-08-29 14:06