zoukankan      html  css  js  c++  java
  • Laravel5.3 流程粗粒度分析之bootstrap

    从laravel入口文件index里面外面不难定位到IlluminateFoundationHttpKernel的handle方法,同样也不难发现handle方法的核心是

    $response = $this->sendRequestThroughRouter($request);

    继续跟踪这个方法

    /**
         * Send the given request through the middleware / router.
         *
         * @param  IlluminateHttpRequest  $request
         * @return IlluminateHttpResponse
         */
        protected function sendRequestThroughRouter($request)
        {
            $this->app->instance('request', $request);
    
            Facade::clearResolvedInstance('request');
    
            $this->bootstrap();
    
            return (new Pipeline($this->app))
                        ->send($request)
                        ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                        ->then($this->dispatchToRouter());
        }

     今天我们要讨论的就是方法中的$this->bootstrap();

    /**
         * Bootstrap the application for HTTP requests.
         *
         * @return void
         */
        public function bootstrap()
        {
            if (! $this->app->hasBeenBootstrapped()) {
                $this->app->bootstrapWith($this->bootstrappers());
            }
        }

    首先,我们先确定这个方法中的$this->app是类IlluminateFoundationApplication以及$this->bootstrappers()如下所示数组

    protected $bootstrappers = [
            'IlluminateFoundationBootstrapDetectEnvironment',
            'IlluminateFoundationBootstrapLoadConfiguration',
            'IlluminateFoundationBootstrapConfigureLogging',
            'IlluminateFoundationBootstrapHandleExceptions',
            'IlluminateFoundationBootstrapRegisterFacades',
            'IlluminateFoundationBootstrapRegisterProviders',
            'IlluminateFoundationBootstrapBootProviders',
        ];

    那么接下来我们查看$this->app->bootstrapWith($this->bootstrappers())

    /**
         * Run the given array of bootstrap classes.
         *
         * @param  array  $bootstrappers
         * @return void
         */
        public function bootstrapWith(array $bootstrappers)
        {
            $this->hasBeenBootstrapped = true;
    
            foreach ($bootstrappers as $bootstrapper) {
                $this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);
    
                $this->make($bootstrapper)->bootstrap($this);
    
                $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
            }
    
        }

    因为是粗粒度分析,我们同样只看这个方法的核心$this->make($bootstrapper)->bootstrap($this),$this->make($bootstrapper)这个我们简单的理解为new $bootstrapper即可,所以这句代码的意思就是将上面$bootstrappers数组里面的每个类实例化并调用他们的bootstrap方法,那么上面那些类都是干什么的呢,其实从类的名字也可以猜出大概的意思了。

    IlluminateFoundationBootstrapDetectEnvironment::bootstrap,从名字看,像是检查环境,具体代码如下:

    /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            if (! $app->configurationIsCached()) {
                $this->checkForSpecificEnvironmentFile($app);
    
                try {
              //$app->environmentPath()默认是我们的basePath,$app->environmentFile()默认是根目录里面的.env文件 (new Dotenv($app->environmentPath(), $app->environmentFile()))->load(); } catch (InvalidPathException $e) { // } } }

     IlluminateFoundationBootstrapLoadConfiguration::bootstrap从名字看,像是加载配置,代码如下

    /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            $items = [];
    
            // First we will see if we have a cache configuration file. If we do, we'll load
            // the configuration items from that file so that it is very quick. Otherwise
            // we will need to spin through every configuration file and load them all.
            if (file_exists($cached = $app->getCachedConfigPath())) {
                $items = require $cached;
    
                $loadedFromCache = true;
            }
    
            $app->instance('config', $config = new Repository($items));
    
            // Next we will spin through all of the configuration files in the configuration
            // directory and load each one into the repository. This will make all of the
            // options available to the developer for use in various parts of this app.
            if (! isset($loadedFromCache)) {
                $this->loadConfigurationFiles($app, $config);
            }
    
            $app->detectEnvironment(function () use ($config) {
                return $config->get('app.env', 'production');
            });
    
            date_default_timezone_set($config['app.timezone']);
    
            mb_internal_encoding('UTF-8');
        }

    IlluminateFoundationBootstrapConfigureLogging::bootstrap从名字看,像是配置日志,代码如下

    /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
         //大概就是默认使用Monolog作为日志记录 $log = $this->registerLogger($app); // If a custom Monolog configurator has been registered for the application // we will call that, passing Monolog along. Otherwise, we will grab the // the configurations for the log system and use it for configuration. if ($app->hasMonologConfigurator()) { call_user_func( $app->getMonologConfigurator(), $log->getMonolog() ); } else { $this->configureHandlers($app, $log); } } /** * Register the logger instance in the container. * * @param IlluminateContractsFoundationApplication $app * @return IlluminateLogWriter */ protected function registerLogger(Application $app) { $app->instance('log', $log = new Writer( new Monolog($app->environment()), $app['events']) ); return $log; }

    IlluminateFoundationBootstrapHandleExceptions::bootstrap看名字,像是处理异常,代码如下

     /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            $this->app = $app;
    
            error_reporting(-1);
    
            set_error_handler([$this, 'handleError']);
    
            set_exception_handler([$this, 'handleException']);
    
            register_shutdown_function([$this, 'handleShutdown']);
    
            if (! $app->environment('testing')) {
                ini_set('display_errors', 'Off');
            }
        }

    IlluminateFoundationBootstrapRegisterFacades::bootstrap看名字像是注册Facades,代码如下,config目录下app配置的aliases配置就是在这里加载的

    /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            Facade::clearResolvedInstances();
    
            Facade::setFacadeApplication($app);
    
            AliasLoader::getInstance($app->make('config')->get('app.aliases', []))->register();
        }

    IlluminateFoundationBootstrapRegisterProviders::bootstrap看名字像是注册Providers,代码如下,config目录下app配置的providers配置就是在这里注册的

    /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            $app->registerConfiguredProviders();
        }

    IlluminateFoundationBootstrapBootProviders::bootstrap看名字像是启动Providers,代码如下,其实就是执行上面注册的Providers数组中各个Provide的boot方法

    /**
         * Bootstrap the given application.
         *
         * @param  IlluminateContractsFoundationApplication  $app
         * @return void
         */
        public function bootstrap(Application $app)
        {
            $app->boot();
        }
    /**
         * Boot the application's service providers.
         *
         * @return void
         */
        public function boot()
        {
            if ($this->booted) {
                return;
            }
    
            // Once the application has booted we will also fire some "booted" callbacks
            // for any listeners that need to do work after this initial booting gets
            // finished. This is useful when ordering the boot-up processes we run.
            $this->fireAppCallbacks($this->bootingCallbacks);
    
            array_walk($this->serviceProviders, function ($p) {
                $this->bootProvider($p);
            });
    
            $this->booted = true;
    
            $this->fireAppCallbacks($this->bootedCallbacks);
        }

    我们经常安装一个扩展功能的时候需要去config里面的app.php的providers和aliases里面添加一些东西,通过以上的大概流程分析,我们就知道laravel是怎么处理这些东西的。

  • 相关阅读:
    数据结构矩阵问题总结
    数据结构:二维ST表
    mysql--时区表问题(Windows环境下)
    mysql--基本命令
    Django2.0--创建缓存表
    git--基本命令
    阿里云主机--重置系统后的登录问题
    链表中倒数第K个结点
    从尾到头打印链表
    替换空格
  • 原文地址:https://www.cnblogs.com/hjyang2012/p/6277199.html
Copyright © 2011-2022 走看看