James Watkins
James Watkins

Reputation: 4954

Why does Spring JMS framework use MessageCreator?

I having a difficult time understanding the pattern that Spring JMS uses for sending messages. The class JmsTemplate takes a MessageCreator as an argument. Like this:

JmsTemplate.send(MessageCreator messageCreator)

There is no option to pass a Message object directly. This seems very anti-Spring because MessageCreator cannot be a Singleton. If it was a singleton, it wouldn't be thread-safe because of this method:

MessageCreator.createMessage(Session session)

The createMessage method only takes a session object. So in order for this object to create a message, it would need to be initialized with some state, and if it has state then it can't be singleton.

So what is the point in forcing me to have a MessageCreator? Because in any real situation MyMessageCreator will always look like this:

public MyMessageCreator(String message) {
    this.message = message;
}
public createMessage(Session session) throws JMSException {
    return session.createTextMessage(message);
}

Because generating the message will always require some beans or other dynamic values. Why do some of the message construction in this class if all of it can't be done?

And if the only reason is so that we have a reference to the Session object, then I'm sure there is a better way to access this instance from a spring bean (by injecting it, getting it from the template itself, or by using some factory method).

Am I missing something? Or is MessageCreator pointless?

Upvotes: 2

Views: 5146

Answers (1)

Stephane Nicoll
Stephane Nicoll

Reputation: 33091

The Session is linked to your send operation, it's not a singleton. And you need to have access to this Session to be able to create a javax.jms.Message.

There is no way for you to pass a javax.jms.Message to JmsTemplate because then you would need the session first to create it and that session is actually managed internally by JmsTemplate.

You should do things the other way around. You should have a method that returns a MessageCreator instead of the Message you would like to build. That method can be placed in a Spring bean and can have whatever injection you need. And since it's a method of yours you can pass whatever dynamic value that you want.

That being said, being able to benefit from Spring 4.0's messaging abstraction (org.springframework.messaging.Message) is a great idea because it would allow you to build the message the way you want in a protocol-independent manner.

I have created SPR-11772 for you.

Upvotes: 4

Related Questions