O modo mais simples de fila no Java RabbitMQ consiste em um produtor e um consumidor.

RabbitMQ Simple Queue

Atualmente, as operações Java com RabbitMQ utilizam principalmente o pacote spring-boot-starter-amqp do Spring Boot, que essencialmente opera a fila usando o Spring AMQP.

1. Tutorial Pré-requisito

Por favor, leia os seguintes capítulos para entender o conhecimento relevante:

2. Pacote de Dependência

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3. Configurar o RabbitMQ

Modifique a configuração do application.yml:

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

4. Declarar a Fila

Configure a fila por meio da classe de configuração do Spring Boot:

package com.tizi365.rabbitmq.config;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QueueConfig {
    @Bean
    public Queue helloQueue() {
        // Declare a fila, e o nome da fila precisa ser único
        return new Queue("hello");
    }
}

Dica: Você pode definir várias filas de acordo com as necessidades do negócio. O nome da fila e o id do bean de Fila precisam ser diferentes. Aqui, o nome do método é o id do bean.

5. Enviar Mensagem

O envio de mensagens requer a classe RabbitTemplate, a qual o Spring Boot já inicializou para nós. Basta injetar a instância:

package com.tizi365.rabbitmq.service;

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class SendService {
    // Injete a instância RabbitTemplate
    @Autowired
    private RabbitTemplate template;
    
    // Injete a fila previamente definida
    @Autowired
    @Qualifier("helloQueue")
    private Queue helloQueue;
    
    // Para demonstração, usamos a tarefa agendada interna do Spring para enviar mensagens regularmente (uma mensagem por segundo)
    @Scheduled(fixedDelay = 1000, initialDelay = 1000)
    public void send() {
        // Conteúdo da mensagem
        String message = "Olá, mundo!";
        // Envie a mensagem
        // O primeiro parâmetro é a chave de roteamento, aqui usamos o nome da fila como chave de roteamento
        // O segundo parâmetro é o conteúdo da mensagem, suportando qualquer tipo desde que suporte serialização
        template.convertAndSend(helloQueue.getName(), message);
        System.out.println("Enviando mensagem '" + message + "'");
    }
}

Dica: Aqui, não estamos usando a troca diretamente. A troca padrão subjacente (troca direta) será utilizada.

6. Receber Mensagem

Para o consumidor, também é simples receber mensagens:

package com.tizi365.rabbitmq.listener;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
// Declara o ouvinte de mensagens, especifica a fila a ser ouvida através do parâmetro `queues`, que precisa ser consistente com o nome da fila anterior
@RabbitListener(queues = "hello")
public class HelloListener {
	// Use RabbitHandler para marcar o manipulador de mensagens, usado para executar a lógica de processamento de mensagens
    @RabbitHandler
    public void receive(String msg) {
        System.out.println("Consumidor - Recebeu mensagem '" + msg + "'");
    }
}

7. Tipo de Mensagem Personalizado

Anteriormente, enviamos uma mensagem do tipo string. Em cenários de negócios reais, preferiríamos enviar diretamente vários tipos de objetos Java personalizados.

Definir um objeto de entidade

package com.tizi365.rabbitmq.domain;

import java.io.Serializable;
import lombok.Data;

// Conteúdo do blog
@Data
public class Blog implements Serializable {
    // id
    private Integer id;
    // título
    private String title;
}

Enviar mensagens do tipo personalizado

Blog blog = new Blog();
blog.setId(100);
blog.setTitle("Tutorial RabbitMQ Tizi365");

// Enviar mensagem
template.convertAndSend(helloQueue.getName(), blog);

Receber mensagens do tipo personalizado

@RabbitHandler
// Basta alterar o parâmetro do método para o tipo de mensagem personalizado
public void receber(Blog msg) {
    System.out.println("Consumidor - Mensagem recebida '" + msg.getTitle() + "'");
}

Utilizar a serialização JSON para o conteúdo da mensagem

Quando o RabbitMQ envia dados de objetos de entidade Java, por padrão, utiliza a ferramenta de serialização de objetos da JDK. Podemos alterá-lo para usar o formato JSON para a serialização de dados, o que permite que outras linguagens consumam mensagens enviadas por Java e torna o formato da mensagem mais legível.

Modifique a classe de configuração anterior e adicione a seguinte configuração para utilizar o parser JSON do Jackson para a serialização e desserialização de dados da mensagem.

@Bean
public Jackson2JsonMessageConverter messageConverter() {
    // Definir o conversor de mensagem padrão
    return new Jackson2JsonMessageConverter();
}