rabbitmq 处理RabbitListener中的泛型类型

h7appiyu  于 2022-11-08  发布在  RabbitMQ
关注(0)|答案(1)|浏览(306)

在我的springboot应用程序中,我创建了一个包含泛型类型的消息,如下所示:

public List<QMessage<T>> composeMessage(String entityName, List<T> input) {
    if (CollectionUtils.isEmpty(input)) {
        return null;
    }

    log.debug("Composing message to send");

    List<QMessage<T>> result = new ArrayList<>();
    input.forEach(el -> {
        QMessage<T> tmp = new QMessage<>();
        tmp.setSourceId(getSourceId(el));
        tmp.setEntityName(entityName);
        tmp.setData(el);
        result.add(tmp);
    });
    return result;
}

public void convertAndPublishList(List<QMessage<T>> items) {
    try {
        log.debug("Converting message to JSON and publishing to RabbitMQ");
        rabbitTemplate.convertAndSend(MQConfig.WD_COMMONS_QUEUE_EXCHANGE, MQConfig.WD_COMMONS_QUEUE_ROUTING_KEY, items);
    } catch (AmqpException e) {
        log.error("Error during message publishing to RabbitMQ. Exception: {}", e.getMessage());
        throw new BlenderProducerException(e.getMessage(), e);
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class QMessage<T> implements Serializable {

    private static final long serialVersionUID = 9095736695643670685L;

    private Long sourceId;

    private String entityName;

    private T data;

}

在侦听器端,我希望以某种方式处理泛型,这就是我所尝试的:

@Slf4j
@Component
@RequiredArgsConstructor
@RabbitListener(queues = MQConfig.WD_COMMONS_QUEUE)
public class WDCommonsListeners {

        @RabbitHandler
        public void handleA(List<QMessage<Dog>> message) {
            System.out.println("handle 1");
        }

        @RabbitHandler
        public void handleB(List<QMessage<Cat>> message) {
            System.out.println("handle 2");
        }

}

但是我收到了这个异常消息:org.springframework.amqp.AmqpException:有效负载类型的方法不明确:数组列表:句柄A和句柄B
考虑Cat和Dog类都是Animal类的扩展
我还尝试了如下未知类型的消息,但我收到的是一个LinkedList而不是一个对象:

@RabbitListener(queues = MQConfig.WD_COMMONS_QUEUE)
public void listener(List<QMessage<?>> message) throws IOException {

    if (!CollectionUtils.isEmpty(message)) {
            for (QMessage<?> msg : message) {
                System.out.println("msg");
            }
    }

也许我必须从消息中获取JSON,然后用ObjectMapper将其转换为对象?

ni65a41a

ni65a41a1#

它只是不检查方法参数的泛型类型:methodParameter.getParameterType().isAssignableFrom(payloadClass)。所以,这就是为什么你会有歧义。
由于您的逻辑很难处理集合及其深度嵌套的泛型类型,我建议使用单个@RabbitListener并手动执行相应的路由。
必须为TypePrecedence.TYPE_ID配置DefaultJackson2JavaTypeMapper,使其在调用侦听器方法之前将传入数据转换为List<QMessage<?>>:https://docs.spring.io/spring-amqp/docs/current/reference/html/#Jackson2JsonMessageConverter-from-message

相关问题