Reputation: 4954
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
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