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讲解了。发现错误劳烦指教,感谢!