深入解析Laravel5.5中的包自动发现Package Auto Discovery
前言
在之前的Laravel版本中,安装包通常需要几个步骤,例如添加服务提供器到app配置文件并注册相关的facades。现在,从Laravel5.5开始,Laravel可以自动检测并注册服务提供器和facades。
本文不是聚焦于他是怎么用的,而是看看它的源码,是怎么实现PackageAutoDiscovery的。
composer.json
一切的起源都是来自composer.json,在使用composer的时候,你可以在post-autoload-dump部分指定你想执行的脚本,比如在Laravel5.5的时候,我们可以看到这样的定义:
"scripts":{ "post-autoload-dump":[ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@phpartisanpackage:discover" ] }
对于postAutoloadDump是很熟悉了,Laravel之前的版本基本都有,它的工作是清理一些缓存,删除一些旧的文件。
我们的关注重点是@phpartisanpackage:discover,也就是会执行@phpartisanpackage:discover这个命令。
这个命令是干嘛的呢?它其实是位于Illuminate\Foundation\Console\PackageDiscoverCommand中,主要是通过执行Illuminate\Foundation\PackageManifest的build()方法来达到发现package的目的。
而PackageManifest早就注册在Laravel的Container中,那么它可以保证每次在启动Laravel的时候都能使用PackageManifest的build()方法,这个build()方法主要的逻辑就是:
找寻vendor/composer/installed.json这个文件,这个文件是composer自己生成的,记录着每一次的composerautoload的classmap。
而此时,Laravel又将这些内容映射到extra.laravel的部分,比如:
"extra":{ "laravel":{ "providers":[ "Barryvdh\\Debugbar\\ServiceProvider" ], "aliases":{ "Debugbar":"Barryvdh\\Debugbar\\Facade" } } }
Laravel首先将以上内容直接读取下来放到一个collection中,然后在去检查下面这个部分的定义,在决定是否需要执行PackageDiscover动作:
"extra":{ "laravel":{ "dont-discover":[ "barryvdh/laravel-debugbar" ] } }
如果你不想执行@phpartisanpackage:discover的发现效果,可以直接在dont-discover的数组里面填上*。
这样判断完成之后,Laravel将collection中需要发现的Package内容保存到一个缓存文件中bootstrap/cache/packages.php:
array( 'providers'=>array( 0=>'Barryvdh\\Debugbar\\ServiceProvider', ), 'aliases'=>array( 'Debugbar'=>'Barryvdh\\Debugbar\\Facade', ), ), );
Laravel怎么拿到Package信息?
这个时候,我们又需要看看Laravel项目启动的时候,主要启动下面的两个服务:
- \Illuminate\Foundation\Bootstrap\RegisterFacades
- \Illuminate\Foundation\Bootstrap\RegisterProvider
而上面的第一个服务会使用Illuminate\Foundation\AliasLoader加载所有的alias,在AliasLoader中:
//inRegisterFacades::bootstrap() AliasLoader::getInstance(array_merge( $app->make('config')->get('app.aliases',[]), $app->make(PackageManifest::class)->aliases() ))->register();
你可以看到,它首先读取app.php的aliases数组,然后与bootstrap/cache/packages.php的packages数组合并,这个时候,就可以获取到所有的packages信息进行发现和自带加载了。这样合并的好处就是,你还是可以直接在app.php中定义你的alias来覆盖自动发现的package,从而保证你的项目还是可以运行得很流畅。
总结
本文将Laravel5.5PackageAutoDiscovery原理和源码梳理的一遍,希望对你了解Laravel5.5PackageAutoDiscovery有所帮助。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。