MessageListenerAdapter is the message listening adapter

In this section, we first write the code and then summarize the use of the MessageListenerAdapter

Code examples:

Under the code address: https://github.com/hmilyos/rabbitmqdemo.git the rabbitmq - API projectCopy the code

1. Simply use the default method

Changes in the previous section SpringAMQP message containers - SimpleMessageListenerContainer RabbitMQConfig messageContainer methodCopy the code
@ Bean / / connectionFactory are to be consistent with the top method name public SimpleMessageListenerContainer messageContainer (connectionFactory connectionFactory) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setQueues(queue001(), queue002(), queue003()); / / to monitor the queue container. SetConcurrentConsumers (1); / / the number of consumers container. SetMaxConcurrentConsumers (5); / / the largest number of consumers container. SetDefaultRequeueRejected (false); / / whether or not to return to the queue container. SetAcknowledgeMode (AcknowledgeMode. AUTO); / / sign for model container. SetExposeListenerChannel (true);
        container.setConsumerTagStrategy(new ConsumerTagStrategy@override public String createConsumerTag(String queue) {return queue + "_"+ UUID.randomUUID().toString(); }}); // 1.1 Adapter mode. The default method has its own name: handleMessage MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate()); container.setMessageListener(adapter);return container;
     }
Copy the code
public class MessageDelegate {

    private static final Logger log= LoggerFactory.getLogger(MessageDelegate.class); / / the handleMessage method name according to the org, springframework. Closer. Rabbit. The listener. / / adapter package The MessageListenerAdapter. ORIGINAL_DEFAULT_LISTENER_METHOD default value to determine the public void handleMessage (byte [] messageBody) {log. The info ("Default method, message content:+ new String(messageBody)); }}Copy the code

The handleMessage method name according to the org. Springframework. Closer. Rabbit. The listener. The adapter package The MessageListenerAdapter. ORIGINAL_DEFAULT_LISTENER_METHOD default value to determine, the source code is as follows

2. Specify a method name of your own

Change the messageContainer above to the following

@ Bean / / connectionFactory are to be consistent with the top method name public SimpleMessageListenerContainer messageContainer (connectionFactory connectionFactory) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setQueues(queue001(), queue002(), queue003()); / / to monitor the queue container. SetConcurrentConsumers (1); / / the number of consumers container. SetMaxConcurrentConsumers (5); / / the largest number of consumers container. SetDefaultRequeueRejected (false); / / whether or not to return to the queue container. SetAcknowledgeMode (AcknowledgeMode. AUTO); / / sign for model container. SetExposeListenerChannel (true);
        container.setConsumerTagStrategy(new ConsumerTagStrategy@override public String createConsumerTag(String queue) {return queue + "_"+ UUID.randomUUID().toString(); }}); //1.2 Adapter mode. You can specify a method name: consumeMessage MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate()); adapter.setDefaultListenerMethod("consumeMessage");
    	container.setMessageListener(adapter);
        return container;
     }
Copy the code

Change the consumption method in MessageDelegate to consumeMessage

    public void consumeMessage(byte[] messageBody) {
        log.info("Byte array method, message content :" + new String(messageBody));
    }
Copy the code

Continue running testSendMessage to see the consumption

Add a converter to convert a byte array to a String

//1.3 Adapter mode. You can also add a converter: TextMessageConverter implements MessageConverter {@override public Message toMessage(Object)  object, MessageProperties messageProperties) throws MessageConversionException {return new Message(object.toString().getBytes(), messageProperties);
    }

    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        String contentType = message.getMessageProperties().getContentType();
        if(null ! = contentType && contentType.contains("text")) {
            return new String(message.getBody());
        }
        returnmessage.getBody(); }}Copy the code

ToMessage is a Java object converted toMessage, and fromMessage is a Message converted to a Java object

Change the messageContainer above to the following

@ Bean / / connectionFactory are to be consistent with the top method name public SimpleMessageListenerContainer messageContainer (connectionFactory connectionFactory) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setQueues(queue001(), queue002(), queue003()); / / to monitor the queue container. SetConcurrentConsumers (1); / / the number of consumers container. SetMaxConcurrentConsumers (5); / / the largest number of consumers container. SetDefaultRequeueRejected (false); / / whether or not to return to the queue container. SetAcknowledgeMode (AcknowledgeMode. AUTO); / / sign for model container. SetExposeListenerChannel (true);
        container.setConsumerTagStrategy(new ConsumerTagStrategy@override public String createConsumerTag(String queue) {return queue + "_"+ UUID.randomUUID().toString(); }}); //1.3 Adapter mode. You can also add a converter: convert the byte array to String MessageListenerAdapter Adapter = new MessageListenerAdapter(new MessageDelegate()); adapter.setDefaultListenerMethod("consumeMessage");
    	adapter.setMessageConverter(new TextMessageConverter());
    	container.setMessageListener(adapter);
        return container;
     }
Copy the code

Key point, we are not using byte arrays anymore!!

//1.3 Adapter mode. Public void consumeMessage(String messageBody) {log.info()"String method, message content :" + messageBody);
    }
Copy the code

Write a unit test case. Note that contentType contains text!!

    @Test
    public void testSendMessage4Text() throws Exception {//1 Create MessageProperties MessageProperties = new MessageProperties(); SendMessage4Text() throws Exception {//1 Create MessageProperties MessageProperties = new MessageProperties(); messageProperties.setContentType("text/plain");
        Message message = new Message(Mq message "1234".getBytes(), messageProperties);

        rabbitTemplate.send("topic001"."spring.abc", message);
    }
Copy the code

Running unit tests

4. The queue name and method name can also be matched one by one

Change the messageContainer above to the following

@ Bean / / connectionFactory are to be consistent with the top method name public SimpleMessageListenerContainer messageContainer (connectionFactory connectionFactory) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setQueues(queue001(), queue002(), queue003()); / / to monitor the queue container. SetConcurrentConsumers (1); / / the number of consumers container. SetMaxConcurrentConsumers (5); / / the largest number of consumers container. SetDefaultRequeueRejected (false); / / whether or not to return to the queue container. SetAcknowledgeMode (AcknowledgeMode. AUTO); / / sign for model container. SetExposeListenerChannel (true);
        container.setConsumerTagStrategy(new ConsumerTagStrategy@override public String createConsumerTag(String queue) {return queue + "_"+ UUID.randomUUID().toString(); }}); // 2 Adapter mode: MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate())); MessageListenerAdapter = new MessageListenerAdapter(new MessageDelegate()); adapter.setMessageConverter(new TextMessageConverter()); Map<String, String> queueOrTagToMethodName = new HashMap<>(); queueOrTagToMethodName.put("queue001"."method1");
    	queueOrTagToMethodName.put("queue002"."method2");
    	adapter.setQueueOrTagToMethodName(queueOrTagToMethodName);
    	container.setMessageListener(adapter);
        return container;
     }
Copy the code

Public void method1(String messageBody) {log.info()"Method1 received the message :" + new String(messageBody));
    }
    public void method2(String messageBody) {
        log.info("Method2 received message content :" + new String(messageBody));
    }
Copy the code

Take a look at the bindings we established earlier

    @Test
    public void testSendMessage4Text() throws Exception {//1 Create MessageProperties MessageProperties = new MessageProperties(); SendMessage4Text() throws Exception {//1 Create MessageProperties MessageProperties = new MessageProperties(); messageProperties.setContentType("text/plain");
        Message message = new Message(Mq message "1234".getBytes(), messageProperties);

        rabbitTemplate.send("topic001"."spring.abc", message);
        rabbitTemplate.send("topic002"."rabbit.abc", message);
    }
Copy the code

Run the test and see the consumption for both queues

To sum up, from the usage code of MessageListenerAdapter above, we can see that it has the following core attributes

  • DefaultListenerMethod defaultListenerMethod name: the name used to set the listener method

  • Delegate Object: The actual, real delegate object used to process messages

  • QueueOrTagMethodName A collection of method names identified by the queue.

  • Queue to method names can be matched one by one.

  • Queue and method name binding, which specifies that messages in the queue will be accepted and processed by the bound method.