laravel5.5简单聊聊\Illuminate\Foundation\Bootstrap\RegisterProviders::class做了什么

场景

  • 简单聊聊\Illuminate\Foundation\Bootstrap\RegisterProviders::class具体做了什么

源码分析

  • public function bootstrap(Application $app){$app->registerConfiguredProviders();} 调用service container 的 registerConfiguredProviders function
  • registerConfiguredProviders function 源码如下
    • $providers = Collection::make($this->config['app.providers'])->partition(function ($provider) {return Str::startsWith($provider, 'Illuminate\\');}); $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]); 获取config/app.php中获取providers 和 自定加载的provider合并到一起的数组
    • (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))->load($providers->collapse()->toArray()); 注册服务
      • manifest = $this->loadManifest(); 读取bootstrap/cache/services.php缓存信息
      • if ($this->shouldRecompile($manifest, $providers)) {$manifest = $this->compileManifest($providers);}
        • 如果bootstrap/cache/services.php文件不存在 则重新编译文件
        • 重新编译services.php文件
          • 封装一个数组, 如果provider是急加载 则 $manifest[‘eager’][] = p r o v i d e r ; 如 果 是 延 迟 加 载 则 ‘ provider; 如果是延迟加载则 ` provider;manifest[‘deferred’][$service] = $provider; m a n i f e s t [ ′ w h e n ′ ] [ manifest['when'][ manifest[when][provider] = $instance->when();`
          • 将上面的数组重新写入bootstrap/cache/services.php
      • foreach ($manifest['eager'] as $provider) { $this->app->register($provider);} 注册eager服务
        • if (($registered = $this->getProvider($provider)) && ! $force) {return $registered;} 如果已经注册了,则直接返回
        • if (is_string($provider)) {$provider = $this->resolveProvider($provider);} 实例化provider
        • if (method_exists($provider, 'register')) {$provider->register();} 执行provider实例的register方法
        • $this->markAsRegistered($provider); 填充服务容器的serviceProviders, loadedProviders属性
      • $this->app->addDeferredServices($manifest['deferred']); 加载延迟服务 , 只是将延迟服务加入到了service container的deferredServices中

小结

  • 这里也可以看到为什么将一个已经存在的provider修改成defer之后,为什么需要执php artisan clear-compiled
    • 上面的情况不会触发重新编译services.php 所以此时延迟加载不能生效
    • php artisan clear-compiled 会删除bootstrap/cache/services.php,这样会触发重新编译
// Illuminate\Foundation\Application 
    /**
     * Register all of the configured providers.
     *
     * @return void
     */
    public function registerConfiguredProviders()
    {
        $providers = Collection::make($this->config['app.providers'])
                        ->partition(function ($provider) {
                            return Str::startsWith($provider, 'Illuminate\\');
                        });
        $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);

        (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                    ->load($providers->collapse()->toArray());
    }
    
    /**
     * Register a service provider with the application.
     *
     * @param  \Illuminate\Support\ServiceProvider|string  $provider
     * @param  array  $options
     * @param  bool   $force
     * @return \Illuminate\Support\ServiceProvider
     */
    public function register($provider, $options = [], $force = false)
    {
        if (($registered = $this->getProvider($provider)) && ! $force) {
            return $registered;
        }

        // If the given "provider" is a string, we will resolve it, passing in the
        // application instance automatically for the developer. This is simply
        // a more convenient way of specifying your service provider classes.
        if (is_string($provider)) {
            $provider = $this->resolveProvider($provider);
        }

        if (method_exists($provider, 'register')) {
            $provider->register();
        }

        $this->markAsRegistered($provider);

        // If the application has already booted, we will call this boot method on
        // the provider class so it has an opportunity to do its boot logic and
        // will be ready for any usage by this developer's application logic.
        if ($this->booted) {
            $this->bootProvider($provider);
        }

        return $provider;
    }

    /**
     * Mark the given provider as registered.
     *
     * @param  \Illuminate\Support\ServiceProvider  $provider
     * @return void
     */
    protected function markAsRegistered($provider)
    {
        $this->serviceProviders[] = $provider;

        $this->loadedProviders[get_class($provider)] = true;
    }

    /**
     * Add an array of services to the application's deferred services.
     *
     * @param  array  $services
     * @return void
     */
    public function addDeferredServices(array $services)
    {
        $this->deferredServices = array_merge($this->deferredServices, $services);
    }

// Illuminate\Foundation\ProviderRepository

   /**
     * Register the application service providers.
     *
     * @param  array  $providers
     * @return void
     */
    public function load(array $providers)
    {
        $manifest = $this->loadManifest();

        // First we will load the service manifest, which contains information on all
        // service providers registered with the application and which services it
        // provides. This is used to know which services are "deferred" loaders.
        if ($this->shouldRecompile($manifest, $providers)) {
            $manifest = $this->compileManifest($providers);
        }

        // Next, we will register events to load the providers for each of the events
        // that it has requested. This allows the service provider to defer itself
        // while still getting automatically loaded when a certain event occurs.
        foreach ($manifest['when'] as $provider => $events) {
            $this->registerLoadEvents($provider, $events);
        }

        // We will go ahead and register all of the eagerly loaded providers with the
        // application so their services can be registered with the application as
        // a provided service. Then we will set the deferred service list on it.
        foreach ($manifest['eager'] as $provider) {
            $this->app->register($provider);
        }

        $this->app->addDeferredServices($manifest['deferred']);
    }

    /**
     * Compile the application service manifest file.
     *
     * @param  array  $providers
     * @return array
     */
    protected function compileManifest($providers)
    {
        // The service manifest should contain a list of all of the providers for
        // the application so we can compare it on each request to the service
        // and determine if the manifest should be recompiled or is current.
        $manifest = $this->freshManifest($providers);

        foreach ($providers as $provider) {
            $instance = $this->createProvider($provider);

            // When recompiling the service manifest, we will spin through each of the
            // providers and check if it's a deferred provider or not. If so we'll
            // add it's provided services to the manifest and note the provider.
            if ($instance->isDeferred()) {
                foreach ($instance->provides() as $service) {
                    $manifest['deferred'][$service] = $provider;
                }

                $manifest['when'][$provider] = $instance->when();
            }

            // If the service providers are not deferred, we will simply add it to an
            // array of eagerly loaded providers that will get registered on every
            // request to this application instead of "lazy" loading every time.
            else {
                $manifest['eager'][] = $provider;
            }
        }

        return $this->writeManifest($manifest);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值