Lumen Event事件源码解析

@liubb  December 11, 2018

有段代码里用到了下文这句,分析整个的执行过程。

event(new UserFollowedSuccessEvent($userId, $actionUserId));

首先看向入口文件 app.php,register方法会调用所传类的boot方法。


$app->register(App\Providers\EventServiceProvider::class);

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        UserFollowedSuccessEvent::class => [
            UserFollowedSuccessEventListener::class
        ],
        UserUnFollowedSuccessEvent::class => [
            UserUnFollowedSuccessEventListener::class
        ],
        CreateFriendShipSuccessEvent::class => [
            CreateFriendShipSuccessEventListener::class
        ],
        TradePushUserInfoEvent::class => [
            TradePushUserInfoEventListener::class
        ],
    ];
}

该类继承了父类,调用了父类的boot方法


public function boot()
    {
        $events = app('events');

        foreach ($this->listen as $event => $listeners) {
            foreach ($listeners as $listener) {
                $events->listen($event, $listener);
            }
        }

        foreach ($this->subscribe as $subscriber) {
            $events->subscribe($subscriber);
        }
    }

分析下 app('events')


function app($make = null)
{
    if (is_null($make)) {
        return Container::getInstance();
    }

    return Container::getInstance()->make($make);
}

public function make($abstract, array $parameters = [])
{
    $abstract = $this->getAlias($abstract);

    if (array_key_exists($abstract, $this->availableBindings) &&
        ! array_key_exists($this->availableBindings[$abstract], $this->ranServiceBinders)) {
        $this->{$method = $this->availableBindings[$abstract]}();

        $this->ranServiceBinders[$method] = true;
    }

    return parent::make($abstract, $parameters);
}

if条件满足,所以执行 $method = $this->availableBindings[$abstract] = registerEventBindings,即执行
$this->registerEventBindings()方法


protected function registerEventBindings()
{
    $this->singleton('events', function () {
        $this->register('Illuminate\Events\EventServiceProvider');

        return $this->make('events');
    });
}

看向EventServiceProvider 类,执行register


public function register()
{
    $this->app->singleton('events', function ($app) {
        return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
            return $app->make(QueueFactoryContract::class);
        });
    });
}

所以 app('events')返回的是个Dispatcher类


接下来分析 上文boot方法里的


foreach ($this->listen as $event => $listeners) {
    foreach ($listeners as $listener) {
        $events->listen($event, $listener);
    }
}

看下 Dispatcher类的listen方法


public function listen($events, $listener)
{
    foreach ((array) $events as $event) {
        if (Str::contains($event, '*')) {
            $this->setupWildcardListen($event, $listener);
        } else {
            $this->listeners[$event][] = $this->makeListener($listener);
        }
    }
}

public function makeListener($listener, $wildcard = false)
{
    if (is_string($listener)) {
        return $this->createClassListener($listener, $wildcard);
    }

    return function ($event, $payload) use ($listener, $wildcard) {
        if ($wildcard) {
            return $listener($event, $payload);
        }

        return $listener(...array_values($payload));
    };
}

public function createClassListener($listener, $wildcard = false)
{
    return function ($event, $payload) use ($listener, $wildcard) {
        if ($wildcard) {
            return call_user_func($this->createClassCallable($listener), $event, $payload);
        }

        return call_user_func_array(
            $this->createClassCallable($listener), $payload
        );
    };
}

protected function createClassCallable($listener)
{
    list($class, $method) = $this->parseClassCallable($listener);

    if ($this->handlerShouldBeQueued($class)) {
        return $this->createQueuedHandlerCallable($class, $method);
    }

    return [$this->container->make($class), $method];
}

protected function parseClassCallable($listener)
{
    return Str::parseCallback($listener, 'handle');
}

$method 默认返回的是 handle

最后就是执行 EventServiceProvider 定义的listen变量里的类的handle方法


添加新评论