laravel Application实例化后两个方法

laravel容器初始化registerBaseServiceProviders方法

  • 上篇讲解了laravel容器的基本使用和原理,这篇继续Application构造方法中的registerBaseServiceProviders方法

    在app调用过registerBaseBindings方法后,打印app实例,发现bindings中存放的确实是闭包,shared为true表示单例绑定,instances中表示容器中可以直接复用的实例
    IlluminateFoundationApplication {#2 ▼
      #basePath: "/home/vagrant/code/test1"
      #hasBeenBootstrapped: false
      #booted: false
      #bootingCallbacks: []
      #bootedCallbacks: []
      #terminatingCallbacks: []
      #serviceProviders: []
      #loadedProviders: []
      #deferredServices: []
      #appPath: null
      #databasePath: null
      #storagePath: null
      #environmentPath: null
      #environmentFile: ".env"
      #isRunningInConsole: null
      #namespace: null
      #resolved: []
      #bindings: array:1 [▼
        "IlluminateFoundationMix" => array:2 [▼
          "concrete" => Closure($container, $parameters = []) {#4 ▶}
          "shared" => true
        ]
      ]
      #methodBindings: []
      #instances: array:12 [▼
        "path" => "/home/vagrant/code/test1/app"
        "path.base" => "/home/vagrant/code/test1"
        "path.lang" => "/home/vagrant/code/test1/resources/lang"
        "path.config" => "/home/vagrant/code/test1/config"
        "path.public" => "/home/vagrant/code/test1/public"
        "path.storage" => "/home/vagrant/code/test1/storage"
        "path.database" => "/home/vagrant/code/test1/database"
        "path.resources" => "/home/vagrant/code/test1/resources"
        "path.bootstrap" => "/home/vagrant/code/test1/bootstrap"
        "app" => IlluminateFoundationApplication {#2}
        "IlluminateContainerContainer" => IlluminateFoundationApplication {#2}
        "IlluminateFoundationPackageManifest" => IlluminateFoundationPackageManifest {#5 ▶}
      ]
      #aliases: []
      #abstractAliases: []
      #extenders: []
      #tags: []
      #buildStack: []
      #with: []
      +contextual: []
      #reboundCallbacks: []
      #globalResolvingCallbacks: []
      #globalAfterResolvingCallbacks: []
      #resolvingCallbacks: []
      #afterResolvingCallbacks: []
    }
    
    下面继续基础服务注册
    /**
     * Register all of the base service providers.
     *
     * @return void
     */
    protected function registerBaseServiceProviders()
    {   
        // 跳转到register方法
        $this->register(new EventServiceProvider($this));
    
        $this->register(new LogServiceProvider($this));
        
        $this->register(new RoutingServiceProvider($this));
    }
            
    /**
     * Register a service provider with the application.
     *
     * @param  IlluminateSupportServiceProvider|string  $provider
     * @param  bool  $force
     * @return IlluminateSupportServiceProvider
     */
    public function register($provider, $force = false)
    {   
        // 跳转到getProvider
        if (($registered = $this->getProvider($provider)) && !$force) {
            // $this->registerBaseServiceProvider没进来
            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.
        // 可以看到register方法 是官方更加推荐的注册服务提供者的方式
        if (is_string($provider)) {
            // 跳转到resolveProvider方法
            // new一个provider
            // 我们可以传递一个字符串 laravel会自动帮我们解析
            // 框架启动后 可以在任何能够拿到app实例地方调用register方法 会执行自定义服务提供者中的register方法 大家可以自行尝试
            $provider = $this->resolveProvider($provider);
        }
    
        $provider->register();
          
        // If there are bindings / singletons set as properties on the provider we
        // will spin through them and register them with the application, which
        // serves as a convenience layer while registering a lot of bindings.
    	
        // laravel为我们提供了方便的进行绑定的方式 那就是将绑定映射写在对应服务提供者中的对应属性中
        // 官方建议没有特殊要求的情况下 写在AppServiceProvider中即可
        if (property_exists($provider, 'bindings')) {
            foreach ($provider->bindings as $key => $value) {
                $this->bind($key, $value);
            }
        }
        
        if (property_exists($provider, 'singletons')) {
            foreach ($provider->singletons as $key => $value) {
                $this->singleton($key, $value);
            }
        }
    	
        // 将已经注册的服务保存到app实例中的对应属性中 serviceProviders loadedProviders
        // 标识该服务已经注册
        $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.
        
        // 如果app已经引导完毕 那么在此刻意调用provider的boot方法
        if ($this->isBooted()) {
            $this->bootProvider($provider);
        }
    
        return $provider;
        // 建议每进行一步都打印下app实例 看到容器中属性的变化即可
    } 
            
    
    app构造方法中的最后一个registerCoreContainerAliases方法
    /**
     * Register the core class aliases in the container.
     *
     * @return void
     */
    public function registerCoreContainerAliases()
    {
        foreach ([
            'app' => [self::class, IlluminateContractsContainerContainer::class, IlluminateContractsFoundationApplication::class, PsrContainerContainerInterface::class],
            'auth' => [IlluminateAuthAuthManager::class, IlluminateContractsAuthFactory::class],
            'auth.driver' => [IlluminateContractsAuthGuard::class],
            'blade.compiler' => [IlluminateViewCompilersBladeCompiler::class],
            'cache' => [IlluminateCacheCacheManager::class, IlluminateContractsCacheFactory::class],
            'cache.store' => [IlluminateCacheRepository::class, IlluminateContractsCacheRepository::class, PsrSimpleCacheCacheInterface::class],
            'cache.psr6' => [SymfonyComponentCacheAdapterPsr16Adapter::class, SymfonyComponentCacheAdapterAdapterInterface::class, PsrCacheCacheItemPoolInterface::class],
            'config' => [IlluminateConfigRepository::class, IlluminateContractsConfigRepository::class],
            'cookie'  => [IlluminateCookieCookieJar::class, IlluminateContractsCookieFactory::class, IlluminateContractsCookieQueueingFactory::class],
            'encrypter'  => [IlluminateEncryptionEncrypter::class, IlluminateContractsEncryptionEncrypter::class],
            'db' => [IlluminateDatabaseDatabaseManager::class, IlluminateDatabaseConnectionResolverInterface::class],
            'db.connection' => [IlluminateDatabaseConnection::class, IlluminateDatabaseConnectionInterface::class],
            'events' => [IlluminateEventsDispatcher::class, IlluminateContractsEventsDispatcher::class],
            'files' => [IlluminateFilesystemFilesystem::class],
            'filesystem' => [IlluminateFilesystemFilesystemManager::class, IlluminateContractsFilesystemFactory::class],
            'filesystem.disk' => [IlluminateContractsFilesystemFilesystem::class],
            'filesystem.cloud' => [IlluminateContractsFilesystemCloud::class],
            'hash' => [IlluminateHashingHashManager::class],
            'hash.driver' => [IlluminateContractsHashingHasher::class],
            'translator' => [IlluminateTranslationTranslator::class, IlluminateContractsTranslationTranslator::class],
            'log' => [IlluminateLogLogManager::class, PsrLogLoggerInterface::class],
            'mailer' => [IlluminateMailMailer::class, IlluminateContractsMailMailer::class, IlluminateContractsMailMailQueue::class],
            'auth.password' => [IlluminateAuthPasswordsPasswordBrokerManager::class, IlluminateContractsAuthPasswordBrokerFactory::class],
            'auth.password.broker' => [IlluminateAuthPasswordsPasswordBroker::class, IlluminateContractsAuthPasswordBroker::class],
            'queue' => [IlluminateQueueQueueManager::class, IlluminateContractsQueueFactory::class, IlluminateContractsQueueMonitor::class],
            'queue.connection' => [IlluminateContractsQueueQueue::class],
            'queue.failer' => [IlluminateQueueFailedFailedJobProviderInterface::class],
            'redirect' => [IlluminateRoutingRedirector::class],
            'redis' => [IlluminateRedisRedisManager::class, IlluminateContractsRedisFactory::class],
            'redis.connection' => [IlluminateRedisConnectionsConnection::class, IlluminateContractsRedisConnection::class],
            'request' => [IlluminateHttpRequest::class, SymfonyComponentHttpFoundationRequest::class],
            'router' => [IlluminateRoutingRouter::class, IlluminateContractsRoutingRegistrar::class, IlluminateContractsRoutingBindingRegistrar::class],
            'session' => [IlluminateSessionSessionManager::class],
            'session.store' => [IlluminateSessionStore::class, IlluminateContractsSessionSession::class],
            'url' => [IlluminateRoutingUrlGenerator::class, IlluminateContractsRoutingUrlGenerator::class],
            'validator' => [IlluminateValidationFactory::class, IlluminateContractsValidationFactory::class],
            'view' => [IlluminateViewFactory::class, IlluminateContractsViewFactory::class],
        ] as $key => $aliases) {
            foreach ($aliases as $alias) {
                // 跳转到alias方法
                $this->alias($key, $alias);
            }
        }
    }
            
    /**
     * Alias a type to a different name.
     *
     * @param  string  $abstract
     * @param  string  $alias
     * @return void
     *
     * @throws LogicException
     */
     // 注册别名
     // 可以在Application类的构造方法最后打印一下我们壮观的app实例
     // 至此得到了bootstrap/app.php下的$app
     public function alias($abstract, $alias)
     {
        if ($alias === $abstract) {
            throw new LogicException("[{$abstract}] is aliased to itself.");
        }
    
        $this->aliases[$alias] = $abstract;
    
        $this->abstractAliases[$abstract][] = $alias;
     }
    

下篇会从bootstrap/app.php讲解了。发现错误劳烦指教,感谢!

原文地址:https://www.cnblogs.com/alwayslinger/p/13404247.html