maatwebsite-Excel 与 队列冲突的解决过程
先写解决办法:
只需要为自己的队列类实现 Illuminate\Contracts\Bus\SelfHandling接口即可(接口是空的,只需简单 implement)
<?php
namespace App\Jobs;
use App\Jobs\Job;
use App\model\Admin\BankModel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Bus\SelfHandling;
class JobTest extends Job implements ShouldQueue,SelfHandling
{
use InteractsWithQueue, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
}
}
解决的过程
项目中要用到maatwebsite-excel和队列
队列所有的配置都是正确的,但就是不执行.看日志发现执行时抛出了异常:
InvalidArgumentException: No handler registered for command [App\Jobs\JobTest]
#0 D:\laragon\www\laravel\vendor\laravelcollective\bus\src\Dispatcher.php(311):
Collective\Bus\Dispatcher->inflectSegment(Object(App\Jobs\JobTest), 0)
进一步排查,发现maatwebsite-excel的依赖包:laravelcollective/bus 引起的
laravelcollective/bus的说明,
This package provides an implementation of the Illuminate\Contracts\Bus\Dispatcher interface that matches the Laravel 5.1.x implementation with separate commands and handlers.
laravelcollective/bus 是 Illuminate\Contracts\Bus\Dispatcher实现
而队列执行的时候是调用 Illuminate\Contracts\Bus\Dispatcher 实现类的 dispatchNow 方法
laravelcollective/bus 的服务提供者注册了对应关系
实现类:
public function register()
{
$this->app->singleton('Collective\Bus\Dispatcher', function ($app) {
return new Dispatcher($app, function () use ($app) {
return $app['Illuminate\Contracts\Queue\Queue'];
});
});
//就是下面这段.
$this->app->alias(
'Collective\Bus\Dispatcher', 'Illuminate\Contracts\Bus\Dispatcher'
);
$this->app->alias(
'Collective\Bus\Dispatcher', 'Illuminate\Contracts\Bus\QueueingDispatcher'
);
}
队列执行的时候实际执行的是Collective\Bus\Dispatcher的dispatchNow方法,代码如下:
use Illuminate\Contracts\Bus\SelfHandling;
......
public function dispatchNow($command, Closure $afterResolving = null)
{
return $this->pipeline->send($command)->through($this->pipes)->then(function ($command) use ($afterResolving) {
//这里判断了$command有没有实现 SelfHandling
if ($command instanceof SelfHandling) {
return $this->container->call([$command, 'handle']);
}
$handler = $this->resolveHandler($command);
if ($afterResolving) {
call_user_func($afterResolving, $handler);
}
return call_user_func(
[$handler, $this->getHandlerMethod($command)], $command
);
});
}
它判断了$command有没有实现 SelfHandling,实现以后才会正常调用队列的handle方法 找到这就找到了解决办法
哈,这是在写 log 吗?
@Summer 写的笔记顺便分享