laravel生命周期超细腻

前言

着手AllInOne项目之前,把laravel项目运行生命周期研究了一下

入口文件:index.php文件(贴关键代码)

$app = require_once __DIR__.'/../bootstrap/app.php';

引入app.php文件。实例化Application类

Application类继承Container,Container统称容器,实质就是把一些类,闭包赋值到类的对应的属性上

	//vendor/laravel/framework/src/Illuminate/Foundation/Application.php
	
    public function __construct($basePath = null)
    {

        if ($basePath) {
            $this->setBasePath($basePath);
        }
        $this->registerBaseBindings(); 

        $this->registerBaseServiceProviders(); 



        $this->registerCoreContainerAliases(); 


    }

t h i s − > s e t B a s e P a t h ( this->setBasePath( this>setBasePath(basePath); 绑定一些基础属性
$this->registerBaseBindings(); 挂载到容器上bindings属性一些地址映射
$this->registerBaseServiceProviders(); //单例挂载到bindings 一些服务提供者

对应方法

  protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));
        $this->register(new LogServiceProvider($this));
        $this->register(new RoutingServiceProvider($this)); //挂载路由
    }

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
); //绑定http请求处理程序

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);//绑定命令行的一些类

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);//绑定处理异常的一些类

绑定到容器 instances属性上

回到index.php文件

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
//var_dump(Illuminate\Http\Request::capture());
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

1.解析绑定到容器上的实例化的类
2.解析请求

handle方法

    /**
     * Handle an incoming HTTP request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();

            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            $this->reportException($e);

            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));

            $response = $this->renderException($request, $e);
        }

        $this->app['events']->dispatch(
            new Events\RequestHandled($request, $response)
        );

        return $response;
    }

关键代码:

$response = t h i s − > s e n d R e q u e s t T h r o u g h R o u t e r ( this->sendRequestThroughRouter( this>sendRequestThroughRouter(request);

送往管道处理

    /**
     * Send the given request through the middleware / router.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    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()
    {

//var_dump($this->bootstrappers());
        if (! $this->app->hasBeenBootstrapped()) {
            $this->app->bootstrapWith($this->bootstrappers());
        }
    }

关键代码:

t h i s − > a p p − > b o o t s t r a p W i t h ( this->app->bootstrapWith( this>app>bootstrapWith(this->bootstrappers());

    /**
     * Run the given array of bootstrap classes.
     *
     * @param  string[]  $bootstrappers
     * @return void
     */
    public function bootstrapWith(array $bootstrappers)
    {

        $this->hasBeenBootstrapped = true;

        foreach ($bootstrappers as $bootstrapper) {
            $this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);

            $this->make($bootstrapper)->bootstrap($this);

            $this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);
        }
    }

关键代码:

t h i s − > m a k e ( this->make( this>make(bootstrapper)->bootstrap($this);
执行服务提供者的 Register方法 \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
执行服务提供者的 boot方法 \Illuminate\Foundation\Bootstrap\BootProviders::class,

 /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        $app->registerConfiguredProviders();
    }
    /**
     * 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());
    }

关键代码:

(new ProviderRepository($this, new Filesystem, t h i s − > g e t C a c h e d S e r v i c e s P a t h ( ) ) ) − > l o a d ( this->getCachedServicesPath())) ->load( this>getCachedServicesPath()))>load(providers->collapse()->toArray());

到服务提供仓库去执行

   /**
     * 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']);
    }

关键代码:

foreach ($manifest[‘eager’] as $provider) {
t h i s − > a p p − > r e g i s t e r ( this->app->register( this>app>register(provider);
}

最后回到
vendor/laravel/framework/src/Illuminate/Foundation/Application.php中执行register方法

    /**
     * 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)
    {
        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);
        }

        $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.
        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);
            }
        }

        $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->isBooted()) {
            $this->bootProvider($provider);
        }

        return $provider;
    }

关键代码:

if (is_string($provider)) {
$provider = t h i s − > r e s o l v e P r o v i d e r ( this->resolveProvider( this>resolveProvider(provider);
}
$provider->register();

boot方法同思想

   /**
     * Boot the application's service providers.
     *
     * @return void
     */
    public function boot()
    {
        if ($this->isBooted()) {
            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);
    }
  /**
     * Boot the given service provider.
     *
     * @param  \Illuminate\Support\ServiceProvider  $provider
     * @return mixed
     */
    protected function bootProvider(ServiceProvider $provider)
    {
        if (method_exists($provider, 'boot')) {
            return $this->call([$provider, 'boot']);
        }
    }

回到 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php sendRequestThroughRouter方法

  /**
     * Send the given request through the middleware / router.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    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());
    }

关键代码:
这边就是处理中间件和分发路由了

return (new Pipeline( t h i s − > a p p ) ) − > s e n d ( this->app)) ->send( this>app))>send(request)
->through($this->app->shouldSkipMiddleware() ? [] : t h i s − > m i d d l e w a r e ) − > t h e n ( this->middleware) ->then( this>middleware)>then(this->dispatchToRouter());

待续…
有错误的地方留言指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值