Laravel8:事件系統(tǒng)源代碼分析

這篇文檔是分析Laravel事件系統(tǒng)。

在生命周期中,注冊event服務(wù)

在Laravel框架生命周期中,在最開始實(shí)例應(yīng)用程序時(shí)

$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

Application 類的構(gòu)造函數(shù)里,會(huì)執(zhí)行注冊基礎(chǔ)服務(wù)提供者,其中就有Event事件服務(wù)提供者。

protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));
    }

然后執(zhí)行了EventServiceProvider類中的register方法。

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

容器中注冊綁定了events服務(wù),對應(yīng)于new Dispatcher()對象。

自此就有了$app['events']

項(xiàng)目中EventServiceProvider 服務(wù)提供者類

在App\Providers\目錄中有一個(gè)EventServiceProvider ,在這個(gè)服務(wù)提供者里,可以通過$listen 屬性,注冊事件和對應(yīng)的偵聽器

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        Kindle::class=>[JujuListener::class]
    ];

可以在boot()方法中,手動(dòng)注冊事件.

public function boot()
{
    Event::listen(function (PodcastProcessed $event) {
        //
    });
}

在Laravel框架生命周期運(yùn)行流程里,會(huì)遍歷所有的服務(wù)提供者類,然后執(zhí)行其內(nèi)部定義的register()方法。

EventServiceProvider 的父類是 Illuminate\Foundation\Support\Providers\EventServiceProvider ,它有一個(gè)register()方法。

public function register()
    {
        $this->booting(function () {
            $events = $this->getEvents();

            foreach ($events as $event => $listeners) {
                foreach (array_unique($listeners) as $listener) {
                    Event::listen($event, $listener);
                }
            }

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

調(diào)用booting()方法,然后傳遞一個(gè)匿名函數(shù)。那么booting()方法定義于它的父類中。

它的父類是Illuminate\Support\ServiceProvider

    public function booting(Closure $callback)
    {
        $this->bootingCallbacks[] = $callback;
    }

把上面的匿名函數(shù),注冊到$this->bootingCallbacks 中。

事件注冊流程分析

事件系統(tǒng),可以通過外觀類Event來調(diào)用。

 use Illuminate\Support\Facades\Event;

操作方法是在 App\Providers\EventServiceProvider類中,操作$listen屬性,或者是在boot()方法中,使用Event::listen()方法注冊事件。

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use App\Events\Kindle;
use App\Listeners\JujuListener;
class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        Kindle::class=>[JujuListener::class]
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        Event::listen(function(){
            

        });
    }
}

注冊完畢后,在控制器中引入事件類,然后使用event()全局函數(shù),將事件對應(yīng)作為參數(shù)傳入其中。

use App\Events\Kindle;


public function indexAction()
{
    event(new Kindle());
}

event()函數(shù)定義在:Illuminate\Foundation\helpers.php文件中

function event(...$args)
{
        return app('events')->dispatch(...$args);
}

因此我們將從dispatcher(事件類) 中的 dispatch()方法,做為入口,進(jìn)行流程分析。

1 dispatch()方法分析

作用:啟動(dòng)事件并呼叫聽眾

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容