laravel源碼分析-隊列Queue
laravel 源碼分析具體注釋見 //github.com/FX-Max/source-analysis-laravel
前言
隊列 (Queue) 是 laravel 中比較常用的一個功能,隊列的目的是將耗時的任務延時處理,比如發送郵件,從而大幅度縮短 Web 請求和響應的時間。本文我們就來分析下隊列創建和執行的源碼。
隊列任務的創建
先通過命令創建一個 Job 類,成功之後會創建如下文件 laravel-src/laravel/app/Jobs/DemoJob.php。
> php artisan make:job DemoJob
> Job created successfully.
下面我們來分析一下 Job 類的具體生成過程。
執行 php artisan make:job DemoJob
後,會觸發調用如下方法。
laravel-src/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php
/**
* Register the command.
* [A] make:job 時觸發的方法
* @return void
*/
protected function registerJobMakeCommand()
{
$this->app->singleton('command.job.make', function ($app) {
return new JobMakeCommand($app['files']);
});
}
接著我們來看下 JobMakeCommand 這個類,這個類裡面沒有過多的處理邏輯,處理方法在其父類中。
class JobMakeCommand extends GeneratorCommand
我們直接看父類中的處理方法,GeneratorCommand->handle(),以下是該方法中的主要方法。
public function handle()
{
// 獲取類名
$name = $this->qualifyClass($this->getNameInput());
// 獲取文件路徑
$path = $this->getPath($name);
// 創建目錄和文件
$this->makeDirectory($path);
// buildClass() 通過模板獲取新類文件的內容
$this->files->put($path, $this->buildClass($name));
// $this->type 在子類中定義好了,例如 JobMakeCommand 中 type = 'Job'
$this->info($this->type.' created successfully.');
}
方法就是通過目錄和文件,創建對應的類文件,至於新文件的內容,都是基於已經設置好的模板來創建的,具體的內容在 buildClass($name) 方法中。
protected function buildClass($name)
{
// 得到類文件模板,getStub() 在子類中有實現,具體看 JobMakeCommand
$stub = $this->files->get($this->getStub());
// 用實際的name來替換模板中的內容,都是關鍵詞替換
return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
}
獲取模板文件
protected function getStub()
{
return $this->option('sync')
? __DIR__.'/stubs/job.stub'
: __DIR__.'/stubs/job-queued.stub';
}
job.stub
<?php
/**
* job 類的生成模板
*/
namespace DummyNamespace;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
class DummyClass
{
use Dispatchable, Queueable;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
job-queued.stub
<?php
/**
* job 類的生成模板
*/
namespace DummyNamespace;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class DummyClass implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
下面看一下前面我們創建的一個Job類,DemoJob.php,就是來源於模板 job-queued.stub。
<?php
/**
* job 類的生成模板
*/
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class DemoJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
至此,我們已經大致明白了隊列任務類是如何創建的了。下面我們來分析下其是如何生效運行的。