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
如有什么错误,欢迎提出、讨论,大家共同进步 _