laravel Application实例化后两个方法

Posted alwayslinger

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了laravel Application实例化后两个方法相关的知识,希望对你有一定的参考价值。

laravel容器初始化registerBaseServiceProviders方法

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

    在app调用过registerBaseBindings方法后,打印app实例,发现bindings中存放的确实是闭包,shared为true表示单例绑定,instances中表示容器中可以直接复用的实例
    Illuminate\Foundation\Application {#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 [▼
        "Illuminate\Foundation\Mix" => 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" => Illuminate\Foundation\Application {#2}
        "Illuminate\Container\Container" => Illuminate\Foundation\Application {#2}
        "Illuminate\Foundation\PackageManifest" => Illuminate\Foundation\PackageManifest {#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  \Illuminate\Support\ServiceProvider|string  $provider
     * @param  bool  $force
     * @return \Illuminate\Support\ServiceProvider
     */
    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, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
            ‘auth‘ => [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class],
            ‘auth.driver‘ => [\Illuminate\Contracts\Auth\Guard::class],
            ‘blade.compiler‘ => [\Illuminate\View\Compilers\BladeCompiler::class],
            ‘cache‘ => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
            ‘cache.store‘ => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class, \Psr\SimpleCache\CacheInterface::class],
            ‘cache.psr6‘ => [\Symfony\Component\Cache\Adapter\Psr16Adapter::class, \Symfony\Component\Cache\Adapter\AdapterInterface::class, \Psr\Cache\CacheItemPoolInterface::class],
            ‘config‘ => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
            ‘cookie‘  => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class],
            ‘encrypter‘  => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class],
            ‘db‘ => [\Illuminate\Database\DatabaseManager::class, \Illuminate\Database\ConnectionResolverInterface::class],
            ‘db.connection‘ => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
            ‘events‘ => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
            ‘files‘ => [\Illuminate\Filesystem\Filesystem::class],
            ‘filesystem‘ => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class],
            ‘filesystem.disk‘ => [\Illuminate\Contracts\Filesystem\Filesystem::class],
            ‘filesystem.cloud‘ => [\Illuminate\Contracts\Filesystem\Cloud::class],
            ‘hash‘ => [\Illuminate\Hashing\HashManager::class],
            ‘hash.driver‘ => [\Illuminate\Contracts\Hashing\Hasher::class],
            ‘translator‘ => [\Illuminate\Translation\Translator::class, \Illuminate\Contracts\Translation\Translator::class],
            ‘log‘ => [\Illuminate\Log\LogManager::class, \Psr\Log\LoggerInterface::class],
            ‘mailer‘ => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class],
            ‘auth.password‘ => [\Illuminate\Auth\Passwords\PasswordBrokerManager::class, \Illuminate\Contracts\Auth\PasswordBrokerFactory::class],
            ‘auth.password.broker‘ => [\Illuminate\Auth\Passwords\PasswordBroker::class, \Illuminate\Contracts\Auth\PasswordBroker::class],
            ‘queue‘ => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class],
            ‘queue.connection‘ => [\Illuminate\Contracts\Queue\Queue::class],
            ‘queue.failer‘ => [\Illuminate\Queue\Failed\FailedJobProviderInterface::class],
            ‘redirect‘ => [\Illuminate\Routing\Redirector::class],
            ‘redis‘ => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class],
            ‘redis.connection‘ => [\Illuminate\Redis\Connections\Connection::class, \Illuminate\Contracts\Redis\Connection::class],
            ‘request‘ => [\Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class],
            ‘router‘ => [\Illuminate\Routing\Router::class, \Illuminate\Contracts\Routing\Registrar::class, \Illuminate\Contracts\Routing\BindingRegistrar::class],
            ‘session‘ => [\Illuminate\Session\SessionManager::class],
            ‘session.store‘ => [\Illuminate\Session\Store::class, \Illuminate\Contracts\Session\Session::class],
            ‘url‘ => [\Illuminate\Routing\UrlGenerator::class, \Illuminate\Contracts\Routing\UrlGenerator::class],
            ‘validator‘ => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class],
            ‘view‘ => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::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下的
     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讲解了。发现错误劳烦指教,感谢!

以上是关于laravel Application实例化后两个方法的主要内容,如果未能解决你的问题,请参考以下文章

laravel application 容器app

laravel5.5源码阅读草稿——application

核心数据:实例化后谓词为零

实例化后UICollectionVIew NIL

为啥我不能更改实例化后用作属性的结构中的字段?

枚举器在迁移中实例化后修改了集合