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方法 找到这就找到了解决办法

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2
Summer

哈,这是在写 log 吗?

7年前 评论

@Summer 写的笔记顺便分享

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!