Laravel-自动发现扩展包
本文主要讲解Laravel如果基于Composer实现自动发现扩展包
Laravel附带了一个composer.json文件,当一些Laravel包被拉取到本地后,还需要几步手动配置使之能在Laravel项目中使用
- 注册 Service Provider
- 注册 Alias或Facade
- 发布 asset
第一、二步已被 Taylor Otwell 确认有点繁琐,因此联合 Dries Vints 开发并推出了「自动注册 Service Provider 和 Facade」功能
在搜索并安装/更新不同的扩展包时,Composer会触发多个事件,这些事件可供订阅,一旦订阅的事件被触发,可调起一段自定义的代码或一条可执行的命令行.
当Composer生成最终的类加载文件.其中一个名为 post-autoload-dump 的事件将会被触发.而后,Laravel已可访问所有类并且项目可使用这些类了
之所以会这样,是因为Laravel在composer.json文件里订阅了 post-autoload-dump 事件
1 | "scripts": { |
首先,调起postAutoloadDump方法,该方法负责清除之前缓存的services和包.然后运行 package:discover 命令,这是关键所在
找寻扩展包
Illuminate\Foundation\Console\PackageDiscoverCommand
调用 Illuminate\Foundation\PackageManifest
类的 build()
方法. PackageManifest
类里包含 Laravel自动找寻已安装包 的实现
PackageManifest
类在应用启动时就被注册入容器里了(是在 Illuminate\Foundation\Application::registerBaseServiceProviders()
里注册)
在 build()
方法内,Laravel会去寻找 vendor/composer/installed.json
文件(该文件由composer生成),Laravel会映射这个文件的内容并且递归搜索含有 extra.laravel
的包
1 | "extra": { |
然后搜索 composer.json
文件的 extra.laravel.dont-discover
区段来判断是否有指定无需自动发现的包
1 | "extra": { |
你可以添加 *
到数组区段里来告诉laravel不执行自动发现
至此,laravel已经收集好了有关扩展包的信息.接下来是把这些信息写入到 bootstrap/cache/packages.php
文件
1 | return array ( |
注册扩展包
当Laravel Kernel启动时,会有两个 bootstrapper启动器
会被调用到
\Illuminate\Foundation\Bootstrap\RegisterFacades
\Illuminate\Foundation\Bootstrap\RegisterProviders
第一个使用 Illuminate\Foundation\AliasLoader
将所有 Facade
加载到容器里,现在唯一不同的是laravel会把 packages.php
里需要加载的 aliases
都一并加载到容器.(使用 PackageManifest::aliases()
方法来收集这些信息)
1 | // in RegisterFacades::bootstrap() |
如上所示,config/app.php
里配置的 aliases
和 PackageManifest类
的 aliases
合并到一起.
相似地,Service Provider
也是这样注册. RegisterProviders
启动器调用 Foundation\Application::registerConfiguredProviders()
把Laravel从所有扩展包中收集的 Service Provider
注册入容器
1 | $providers = Collection::make($this->config['app.providers']) |
欢迎转载但请附上链接,谢谢。
原文:laravels-package-auto-discovery
如有什么错误,欢迎提出、讨论,大家共同进步 _