spring-jms provides JmsTemplate to hide message sending implementations.
To send Message with current TPIC, one can override JmsTemplate's
protected MessageProducer createProducer(Session session, Destination destination) throws JMSException {
}
method to return a TraceeMessageProducer. But it's not opaque to the client. Another approach is wrap ConnectionFactory and inject it to JmsTemplate:
@Bean
protected ConnectionFactory connectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
TraceeWrappedConnectionFactory traceeWrappedConnectionFactory = new TraceeWrappedConnectionFactory();
traceeWrappedConnectionFactory.setTargetConnectionFactory(activeMQConnectionFactory);
return traceeWrappedConnectionFactory;
}
@Bean
protected JmsTemplate jmsTemplate() {
JmsTemplate template = new JmsTemplate(connectionFactory());
return template;
}
The TraceeWrappedConnectionFactory is actually a DelegatingConnectionFactory which will return a TraceeWrappedConnection for createSession() invocation. TraceeWrappedConnection also follows Delegation Pattern and returns a Delegating TraceeWrappedSession which will return TraceeMessageProducer in the end.
On the receiving side, the only way I find without AOP is provide a subclass of DefaultMessageListenerContainer and overrides invokeListener() or doExecuteListener() like this:
protected void invokeListener(Session session, Message message) throws JMSException {
beforeProcessing(message);
try {
super.invokeListener(session, message);
} finally {
cleanUp();
}
}
For spring-jms 2.x, one can setup the context using:
<bean id="jmsContainer" class="spike.TraceeMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="hi"/>
<property name="messageListener" ref="messageListener"/>
</bean>
For spring-jms 4.x, one more component is needed, TraceeJmsListenerContainerFactory overrides createContainerInstance(), returns TraceeMessageListenerContainer instead of default DefaultMessageListenerContainer:
@Bean
public DefaultJmsListenerContainerFactory myJmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new TraceeJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
return factory;
}
As long as one provided a TraceeWrappedConnectionFactory, the request-reply case is also covered.
spring-jms provides JmsTemplate to hide message sending implementations.
To send Message with current TPIC, one can override JmsTemplate's
method to return a TraceeMessageProducer. But it's not opaque to the client. Another approach is wrap ConnectionFactory and inject it to JmsTemplate:
The TraceeWrappedConnectionFactory is actually a DelegatingConnectionFactory which will return a TraceeWrappedConnection for createSession() invocation. TraceeWrappedConnection also follows Delegation Pattern and returns a Delegating TraceeWrappedSession which will return TraceeMessageProducer in the end.
On the receiving side, the only way I find without AOP is provide a subclass of DefaultMessageListenerContainer and overrides invokeListener() or doExecuteListener() like this:
For spring-jms 2.x, one can setup the context using:
For spring-jms 4.x, one more component is needed, TraceeJmsListenerContainerFactory overrides createContainerInstance(), returns TraceeMessageListenerContainer instead of default DefaultMessageListenerContainer:
As long as one provided a TraceeWrappedConnectionFactory, the request-reply case is also covered.