简体   繁体   中英

Sending spring integration jms message to specific queue (dynamically)

A simple message publisher looks like:

@Service("myPublisher")
public class MyPublisher{

   @Publisher(channel = "myChannel")
   public Message<?> sendMessage (Message<?> message) {
      return message;
   }
}

...and is configures like this:

<int:channel id="myChannel"/>   
<int-jms:outbound-channel-adapter channel="myChannel" destination="defaultDestination" session-transacted="true"/>
<bean class="org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor"/>

The Problem is, this publisher sends messages to a prepared defaultDestination , but I need to send messages to different queues. In my case I need a message queue for every task in my application. The reason is, if I want to abort a task, I must remove the messages from the broker. If there are thousands of messages for one task, it is not a good practice to receive all messages with a selector. I need to to remove all messages of the aborted task from the message broker without receiving of a client. JMS only supports sending and receiving of messages. I must use the broker API (QPID) to remove the messages. The problem is, QPID doesn't support removing of messages by a selector, but it supports removing of queues.

I think, I need a PublisherFactory, with a function like this:

public class PublisherFactory {
    public MyPublisher getPublisher(String destinationName){...};
}

factory.getPublisher("testQueue");

This method should return a publisher that sends messages to the testQueue .

Or a service with a function like this:

public class PublisherService {
    public Message<?> sendMessage(Message<?> message, String desinationName){...};
}

service.sendMessage(new Message("test"), "testQueue");

In short words, all I want, is a service that sends a Message to a specific destination. The destination name should be set either as a param over method call or as a class variable over a factory.

I hope, someone has the solution of my problem. Thanks :)

The <int-jms:outbound-channel-adapter> can be configured not only to the static destination , but with some dynamic behavior to determine destination at runtime using SpEL against request message.

destination-expression="headers.destination"

From other side @Publisher 's AOP allows to build a message to publish not only just with the payload as a return value by default, but with more smart logic. For example:

@Publisher(channel="annotationConfigRegistrationTest")
@Payload("#return + #args.lname")
public String setName(String fname, String lname, @Header("x") int num) {
    return fname + " " + lname;
}

In this case the message to publish will have a payload like return value, plus a lname param. The @Header("x") will populate to that message an x header with num as value.

Since your sendMessage methods returns whole Message<?> , you just need to build a new message there and add mentioned above destination header, based on the stuff for current state.

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM