O modo mais simples de fila no Java RabbitMQ consiste em um produtor e um consumidor.
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();
}