0
# Configuration Support
1
2
Factory classes and configuration support for creating and managing JMS listener containers, annotation processing, and XML namespace support for declarative configuration. Spring JMS provides comprehensive configuration options for both programmatic and declarative setup.
3
4
## Capabilities
5
6
### JmsListenerContainerFactory
7
8
Factory interface for creating JMS listener containers with specific configuration, enabling customizable container creation and management.
9
10
```java { .api }
11
/**
12
* Factory interface for creating JMS listener containers
13
*/
14
public interface JmsListenerContainerFactory<C extends MessageListenerContainer> {
15
16
/**
17
* Create a message listener container for the given endpoint
18
* @param endpoint the JMS listener endpoint to configure
19
* @return the configured message listener container
20
*/
21
C createListenerContainer(JmsListenerEndpoint endpoint);
22
}
23
```
24
25
### AbstractJmsListenerContainerFactory
26
27
Abstract base factory providing common configuration for JMS listener containers with template methods for container customization.
28
29
```java { .api }
30
/**
31
* Abstract base factory for JMS listener containers
32
*/
33
public abstract class AbstractJmsListenerContainerFactory<C extends AbstractMessageListenerContainer>
34
implements JmsListenerContainerFactory<C> {
35
36
// Connection configuration
37
public void setConnectionFactory(ConnectionFactory connectionFactory);
38
public ConnectionFactory getConnectionFactory();
39
40
// Destination configuration
41
public void setDestinationResolver(DestinationResolver destinationResolver);
42
public DestinationResolver getDestinationResolver();
43
public void setPubSubDomain(Boolean pubSubDomain);
44
public Boolean getPubSubDomain();
45
46
// Session configuration
47
public void setSessionAcknowledgeMode(Integer sessionAcknowledgeMode);
48
public void setSessionTransacted(Boolean sessionTransacted);
49
50
// Message handling configuration
51
public void setMessageConverter(MessageConverter messageConverter);
52
public MessageConverter getMessageConverter();
53
public void setErrorHandler(ErrorHandler errorHandler);
54
public ErrorHandler getErrorHandler();
55
56
// Transaction configuration
57
public void setTransactionManager(PlatformTransactionManager transactionManager);
58
public PlatformTransactionManager getTransactionManager();
59
60
// Auto-startup configuration
61
public void setAutoStartup(Boolean autoStartup);
62
public void setPhase(Integer phase);
63
64
// Template methods for container creation and configuration
65
protected abstract C createContainerInstance();
66
protected void configureContainer(C container, JmsListenerEndpoint endpoint);
67
}
68
```
69
70
### DefaultJmsListenerContainerFactory
71
72
Factory for creating DefaultMessageListenerContainer instances with advanced configuration options for dynamic scaling and resource management.
73
74
```java { .api }
75
/**
76
* Factory for DefaultMessageListenerContainer with advanced configuration
77
*/
78
public class DefaultJmsListenerContainerFactory extends AbstractJmsListenerContainerFactory<DefaultMessageListenerContainer> {
79
80
public DefaultJmsListenerContainerFactory();
81
82
// Concurrency configuration
83
public void setConcurrency(String concurrency);
84
public void setMaxConcurrentConsumers(Integer maxConcurrentConsumers);
85
86
// Cache configuration
87
public void setCacheLevel(Integer cacheLevel);
88
public void setCacheLevelName(String cacheLevelName);
89
90
// Recovery configuration
91
public void setRecoveryInterval(Long recoveryInterval);
92
public void setReceiveTimeout(Long receiveTimeout);
93
94
// Task execution configuration
95
public void setTaskExecutor(Executor taskExecutor);
96
public void setMaxMessagesPerTask(Integer maxMessagesPerTask);
97
public void setIdleConsumerLimit(Integer idleConsumerLimit);
98
public void setIdleTaskExecutionLimit(Integer idleTaskExecutionLimit);
99
100
// Backoff configuration
101
public void setBackOff(BackOff backOff);
102
103
@Override
104
protected DefaultMessageListenerContainer createContainerInstance();
105
}
106
```
107
108
### SimpleJmsListenerContainerFactory
109
110
Factory for creating SimpleMessageListenerContainer instances with simpler configuration for basic use cases.
111
112
```java { .api }
113
/**
114
* Factory for SimpleMessageListenerContainer with basic configuration
115
*/
116
public class SimpleJmsListenerContainerFactory extends AbstractJmsListenerContainerFactory<SimpleMessageListenerContainer> {
117
118
public SimpleJmsListenerContainerFactory();
119
120
// Concurrency configuration
121
public void setConcurrentConsumers(Integer concurrentConsumers);
122
123
// Task execution configuration
124
public void setTaskExecutor(Executor taskExecutor);
125
126
// Pub/Sub configuration
127
public void setPubSubNoLocal(Boolean pubSubNoLocal);
128
public void setSubscriptionDurable(Boolean subscriptionDurable);
129
public void setSubscriptionShared(Boolean subscriptionShared);
130
public void setClientId(String clientId);
131
132
@Override
133
protected SimpleMessageListenerContainer createContainerInstance();
134
}
135
```
136
137
### JmsListenerEndpointRegistrar
138
139
Central class for managing JMS listener endpoint registration, providing programmatic configuration of listener endpoints and container factories.
140
141
```java { .api }
142
/**
143
* Helper for registering JMS listener endpoints programmatically
144
*/
145
public class JmsListenerEndpointRegistrar implements BeanFactoryAware, InitializingBean {
146
147
public JmsListenerEndpointRegistrar();
148
149
// Registry configuration
150
public void setEndpointRegistry(JmsListenerEndpointRegistry endpointRegistry);
151
public JmsListenerEndpointRegistry getEndpointRegistry();
152
153
// Container factory configuration
154
public void setContainerFactory(JmsListenerContainerFactory<?> containerFactory);
155
public void setContainerFactoryBeanName(String containerFactoryBeanName);
156
157
// Message handler configuration
158
public void setMessageHandlerMethodFactory(MessageHandlerMethodFactory messageHandlerMethodFactory);
159
160
// Endpoint registration
161
public void registerEndpoint(JmsListenerEndpoint endpoint);
162
public void registerEndpoint(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory);
163
164
// Bean factory integration
165
public void setBeanFactory(BeanFactory beanFactory);
166
167
// Lifecycle methods
168
public void afterPropertiesSet();
169
}
170
```
171
172
### JmsListenerEndpointRegistry
173
174
Registry that manages JMS listener containers and provides lifecycle control for all registered endpoints.
175
176
```java { .api }
177
/**
178
* Registry for managing JMS listener endpoints and containers
179
*/
180
public class JmsListenerEndpointRegistry implements DisposableBean, SmartLifecycle, ApplicationContextAware {
181
182
public JmsListenerEndpointRegistry();
183
184
// Container registration
185
public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory);
186
public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory, boolean startImmediately);
187
188
// Container access
189
public MessageListenerContainer getListenerContainer(String id);
190
public Set<String> getListenerContainerIds();
191
public Collection<MessageListenerContainer> getListenerContainers();
192
193
// Lifecycle management
194
public void start();
195
public void stop();
196
public void stop(Runnable callback);
197
public boolean isRunning();
198
public boolean isAutoStartup();
199
public int getPhase();
200
201
// Registry management
202
public void unregisterListenerContainer(String id);
203
public void destroy();
204
}
205
```
206
207
### MessageHandlerMethodFactory
208
209
Factory interface for creating method handlers for JMS listener endpoints, enabling customization of method invocation and argument resolution.
210
211
```java { .api }
212
/**
213
* Factory for creating method handlers for JMS listener endpoints
214
*/
215
public interface MessageHandlerMethodFactory {
216
217
/**
218
* Create a method handler for the given method
219
* @param bean the bean instance
220
* @param method the method to invoke
221
* @return the invocable handler method
222
*/
223
InvocableHandlerMethod createInvocableHandlerMethod(Object bean, Method method);
224
}
225
226
/**
227
* Default implementation of MessageHandlerMethodFactory
228
*/
229
public class DefaultMessageHandlerMethodFactory implements MessageHandlerMethodFactory, BeanFactoryAware {
230
231
public DefaultMessageHandlerMethodFactory();
232
233
// Configuration
234
public void setMessageConverter(MessageConverter messageConverter);
235
public void setValidator(Validator validator);
236
public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);
237
public void setBeanFactory(BeanFactory beanFactory);
238
239
// Initialization
240
public void afterPropertiesSet();
241
242
@Override
243
public InvocableHandlerMethod createInvocableHandlerMethod(Object bean, Method method);
244
}
245
```
246
247
### Annotation Processing Support
248
249
Classes for processing @JmsListener annotations and integrating with Spring's application context.
250
251
```java { .api }
252
/**
253
* Bean post-processor for processing @JmsListener annotations
254
*/
255
public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered, BeanFactoryAware,
256
BeanClassLoaderAware, EnvironmentAware, SmartInitializingSingleton {
257
258
public static final String DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME = "jmsListenerContainerFactory";
259
260
// Configuration
261
public void setContainerFactoryBeanName(String containerFactoryBeanName);
262
public void setEndpointRegistry(JmsListenerEndpointRegistry endpointRegistry);
263
public void setMessageHandlerMethodFactory(MessageHandlerMethodFactory messageHandlerMethodFactory);
264
265
// Bean post-processing
266
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
267
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
268
269
// Ordering
270
public int getOrder();
271
}
272
273
/**
274
* Bootstrap configuration for JMS annotation processing
275
*/
276
@Configuration
277
@ConditionalOnClass(EnableJms.class)
278
public class JmsBootstrapConfiguration {
279
280
@Bean(name = JmsListenerConfigurer.JMS_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
281
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
282
public JmsListenerAnnotationBeanPostProcessor jmsListenerAnnotationProcessor();
283
284
@Bean(name = JmsListenerConfigurer.JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME)
285
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
286
public JmsListenerEndpointRegistry defaultJmsListenerEndpointRegistry();
287
}
288
```
289
290
### XML Configuration Support
291
292
Namespace handlers and parsers for XML-based JMS configuration, enabling declarative configuration through Spring XML.
293
294
```java { .api }
295
/**
296
* Namespace handler for JMS XML configuration
297
*/
298
public class JmsNamespaceHandler extends NamespaceHandlerSupport {
299
300
@Override
301
public void init();
302
}
303
304
/**
305
* Abstract parser for listener container XML elements
306
*/
307
public abstract class AbstractListenerContainerParser extends AbstractSingleBeanDefinitionParser {
308
309
@Override
310
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder);
311
312
// Template methods for container-specific parsing
313
protected abstract String getContainerClassName();
314
protected abstract void parseListenerConfiguration(Element element, BeanDefinitionBuilder builder);
315
}
316
317
/**
318
* Parser for JMS listener container XML elements
319
*/
320
public class JmsListenerContainerParser extends AbstractListenerContainerParser {
321
322
private static final String CONTAINER_TYPE_ATTRIBUTE = "container-type";
323
private static final String CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
324
private static final String TASK_EXECUTOR_ATTRIBUTE = "task-executor";
325
private static final String DESTINATION_RESOLVER_ATTRIBUTE = "destination-resolver";
326
private static final String MESSAGE_CONVERTER_ATTRIBUTE = "message-converter";
327
328
@Override
329
protected String getContainerClassName();
330
331
@Override
332
protected void parseListenerConfiguration(Element element, BeanDefinitionBuilder builder);
333
}
334
```
335
336
**Usage Examples:**
337
338
```java
339
import org.springframework.jms.config.*;
340
import org.springframework.jms.annotation.*;
341
342
// Java-based configuration
343
@Configuration
344
@EnableJms
345
public class JmsConfiguration implements JmsListenerConfigurer {
346
347
// Default container factory
348
@Bean
349
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
350
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
351
factory.setConnectionFactory(connectionFactory());
352
factory.setDestinationResolver(destinationResolver());
353
factory.setMessageConverter(messageConverter());
354
factory.setConcurrency("1-10");
355
factory.setSessionTransacted(false);
356
factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
357
factory.setErrorHandler(new DefaultErrorHandler());
358
return factory;
359
}
360
361
// High-throughput container factory
362
@Bean("highThroughputFactory")
363
public DefaultJmsListenerContainerFactory highThroughputFactory() {
364
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
365
factory.setConnectionFactory(connectionFactory());
366
factory.setConcurrency("5-50");
367
factory.setMaxMessagesPerTask(10);
368
factory.setReceiveTimeout(5000L);
369
factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
370
return factory;
371
}
372
373
// Simple container factory
374
@Bean("simpleFactory")
375
public SimpleJmsListenerContainerFactory simpleFactory() {
376
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
377
factory.setConnectionFactory(connectionFactory());
378
factory.setConcurrentConsumers(2);
379
factory.setPubSubDomain(true); // For topics
380
return factory;
381
}
382
383
// Transaction-aware container factory
384
@Bean("transactionalFactory")
385
public DefaultJmsListenerContainerFactory transactionalFactory() {
386
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
387
factory.setConnectionFactory(connectionFactory());
388
factory.setTransactionManager(jmsTransactionManager());
389
factory.setSessionTransacted(true);
390
factory.setConcurrency("1-5");
391
return factory;
392
}
393
394
@Override
395
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
396
// Set default container factory
397
registrar.setContainerFactory(jmsListenerContainerFactory());
398
399
// Custom message handler factory for argument resolution
400
registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
401
}
402
403
@Bean
404
public MessageHandlerMethodFactory messageHandlerMethodFactory() {
405
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
406
factory.setMessageConverter(messageConverter());
407
return factory;
408
}
409
}
410
411
// Service using different container factories
412
@Service
413
public class MessageProcessingService {
414
415
// Default container factory
416
@JmsListener(destination = "standard.queue")
417
public void processStandardMessage(String message) {
418
System.out.println("Standard: " + message);
419
}
420
421
// High-throughput container factory
422
@JmsListener(destination = "bulk.queue", containerFactory = "highThroughputFactory")
423
public void processBulkMessage(String message) {
424
System.out.println("Bulk: " + message);
425
}
426
427
// Simple container factory for topics
428
@JmsListener(destination = "notification.topic", containerFactory = "simpleFactory")
429
public void processNotification(String notification) {
430
System.out.println("Notification: " + notification);
431
}
432
433
// Transactional container factory
434
@JmsListener(destination = "transaction.queue", containerFactory = "transactionalFactory")
435
@Transactional
436
public void processTransactionalMessage(Order order) {
437
// Transactional processing
438
orderService.processOrder(order);
439
auditService.logOrderProcessing(order.getId());
440
}
441
}
442
443
// Programmatic endpoint registration
444
@Component
445
public class ProgrammaticJmsConfiguration {
446
447
@Autowired
448
private JmsListenerEndpointRegistrar registrar;
449
450
@Autowired
451
private DefaultJmsListenerContainerFactory containerFactory;
452
453
@PostConstruct
454
public void configureListeners() {
455
// Create endpoint programmatically
456
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
457
endpoint.setId("programmatic-listener");
458
endpoint.setDestination("dynamic.queue");
459
endpoint.setMessageListener(message -> {
460
System.out.println("Programmatic listener: " + message);
461
});
462
463
// Register endpoint
464
registrar.registerEndpoint(endpoint, containerFactory);
465
}
466
}
467
468
// Dynamic listener management
469
@Service
470
public class DynamicListenerService {
471
472
@Autowired
473
private JmsListenerEndpointRegistry registry;
474
475
@Autowired
476
private DefaultJmsListenerContainerFactory containerFactory;
477
478
public void startDynamicListener(String destinationName, MessageListener listener) {
479
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
480
endpoint.setId("dynamic-" + destinationName);
481
endpoint.setDestination(destinationName);
482
endpoint.setMessageListener(listener);
483
484
registry.registerListenerContainer(endpoint, containerFactory, true);
485
}
486
487
public void stopListener(String listenerId) {
488
MessageListenerContainer container = registry.getListenerContainer(listenerId);
489
if (container != null) {
490
container.stop();
491
}
492
}
493
494
public void removeListener(String listenerId) {
495
registry.unregisterListenerContainer(listenerId);
496
}
497
498
public Collection<String> getActiveListeners() {
499
return registry.getListenerContainerIds();
500
}
501
}
502
```
503
504
### XML Configuration Example
505
506
```xml
507
<?xml version="1.0" encoding="UTF-8"?>
508
<beans xmlns="http://www.springframework.org/schema/beans"
509
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
510
xmlns:jms="http://www.springframework.org/schema/jms"
511
xsi:schemaLocation="
512
http://www.springframework.org/schema/beans
513
http://www.springframework.org/schema/beans/spring-beans.xsd
514
http://www.springframework.org/schema/jms
515
http://www.springframework.org/schema/jms/spring-jms.xsd">
516
517
<!-- Enable annotation-driven JMS -->
518
<jms:annotation-driven container-factory="jmsContainerFactory" />
519
520
<!-- JMS listener container -->
521
<jms:listener-container
522
connection-factory="connectionFactory"
523
task-executor="taskExecutor"
524
destination-resolver="destinationResolver"
525
message-converter="messageConverter"
526
concurrency="1-10">
527
528
<jms:listener destination="order.queue" ref="orderService" method="processOrder" />
529
<jms:listener destination="notification.topic" ref="notificationService" method="handleNotification" />
530
</jms:listener-container>
531
532
<!-- Container factory definition -->
533
<bean id="jmsContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
534
<property name="connectionFactory" ref="connectionFactory" />
535
<property name="concurrency" value="1-5" />
536
<property name="sessionTransacted" value="false" />
537
</bean>
538
</beans>
539
```