[컴][웹][php] laravel 에서 ServiceProvider 의 호출 과정

라라벨 분석 / laravel 분석 / 라라벨에서 서비스 프로바이더 호출 /


Laravel 에서 ServiceProvider 가 호출되는 과정



index.php

browser 에서 url 쳐서 request 를 하면 일단 server.php 를 거쳐서
./public/index.php 로 가게 된다.

server.php 는 apache 등의 web server 의 emulation 을 하기 때문에 실제로 publishing 에 쓰이지는 않는다.

결국 index.php 가 시작점이라고 보면 된다.

여기서 kernel 를 만드는데,

...

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()

);

$response->send();
$kernel->terminate($request, $response);


이 kernel 은 아래 같은 데이터 구조(data structure)이다.
App\Http\Kernel
    middleware:array(4)
    middlewareGroups:array(2)
    routeMiddleware:array(6)
    app:Illuminate\Foundation\Application
    router:Illuminate\Routing\Router
    bootstrappers:array(6)
    middlewarePriority:array(6)



ServiceProvider의 boot() 호출

처음에 index.php 를 호출하면, 여기서 Kernel->handle() 을 호출한다. 그래서 결국 Application::boot() 을 호출하는데, 여기서 ServiceProvider 들에 대해서  Application->bootProvider() 를 호출한다. (아래 stack trace 참고)

source 를 보면 알지만, bootProvider() 에서는 Application 이 가지고 있는 ServiceProvider 들중에 boot() 함수가 있는 녀석만 call 을 하게 된다.


// Stack trace
index.php
Illuminate\Foundation\Http\Kernel->handle
Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter
Illuminate\Foundation\Http\Kernel->bootstrap
Illuminate\Foundation\Application->bootstrapWith
Illuminate\Foundation\Bootstrap\BootProviders->bootstrap
Illuminate\Foundation\Application->boot
Illuminate\Foundation\Application->bootProvider






class BootProviders
{
    public function bootstrap(Application $app)
    {
        $app->boot();
    }
}


class Application extends Container implements ApplicationContract, HttpKernelInterface
{
    /**
     * The Laravel framework version.
     *
     * @var string
     */
    const VERSION = '5.4.23';
    ...
    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);
    }




$this->serviceProviders
 Illuminate\Events\EventServiceProvider
 Illuminate\Log\LogServiceProvider
 Illuminate\Routing\RoutingServiceProvider
 Illuminate\Auth\AuthServiceProvider
 Illuminate\Cookie\CookieServiceProvider
 Illuminate\Database\DatabaseServiceProvider
 Illuminate\Encryption\EncryptionServiceProvider
 Illuminate\Filesystem\FilesystemServiceProvider
 Illuminate\Foundation\Providers\FormRequestServiceProvider
 Illuminate\Foundation\Providers\FoundationServiceProvider
 Illuminate\Notifications\NotificationServiceProvider
 Illuminate\Pagination\PaginationServiceProvider
 Illuminate\Session\SessionServiceProvider
 Illuminate\View\ViewServiceProvider
 App\Providers\AppServiceProvider
 App\Providers\AuthServiceProvider
 App\Providers\EventServiceProvider
 App\Providers\RouteServiceProvider



class Application extends Container implements ApplicationContract, HttpKernelInterface
{
  
    ...
    protected function bootProvider(ServiceProvider $provider)
    {
        if (method_exists($provider, 'boot')) {
            return $this->call([$provider, 'boot']);
        }
    }
   ...
}








댓글 없음:

댓글 쓰기