0
# Binding Management
1
2
The binding management framework provides centralized lifecycle management for message bindings, proxy creation, and channel configuration. It handles the creation, configuration, and lifecycle of connections between application components and messaging infrastructure.
3
4
## Capabilities
5
6
### Binding Service
7
8
Central service for managing all message bindings in a Spring Cloud Stream application.
9
10
```java { .api }
11
/**
12
* Central service for managing bindings between applications and message brokers.
13
*/
14
public class BindingService implements BeanFactoryAware, DisposableBean, ApplicationContextAware {
15
16
/**
17
* Bind a consumer to the specified input name.
18
* @param inputTarget the consumer binding target
19
* @param inputName the logical input name
20
* @return collection of created bindings
21
*/
22
public Collection<Binding<Object>> bindConsumer(Object inputTarget, String inputName);
23
24
/**
25
* Bind a producer to the specified output name.
26
* @param outputTarget the producer binding target
27
* @param outputName the logical output name
28
* @return the created binding
29
*/
30
public Binding<MessageChannel> bindProducer(Object outputTarget, String outputName);
31
32
/**
33
* Unbind all consumers for the specified input name.
34
* @param inputName the logical input name
35
*/
36
public void unbindConsumers(String inputName);
37
38
/**
39
* Unbind all producers for the specified output name.
40
* @param outputName the logical output name
41
*/
42
public void unbindProducers(String outputName);
43
44
/**
45
* Get all consumer bindings.
46
* @return map of consumer bindings keyed by input name
47
*/
48
public Map<String, List<Binding<Object>>> getConsumerBindings();
49
50
/**
51
* Get all producer bindings.
52
* @return map of producer bindings keyed by output name
53
*/
54
public Map<String, Binding<MessageChannel>> getProducerBindings();
55
56
public void setBeanFactory(BeanFactory beanFactory);
57
public void setApplicationContext(ApplicationContext applicationContext);
58
public void destroy();
59
}
60
```
61
62
### Bindable Interface
63
64
Interface for objects that can have their inputs and outputs bound to messaging infrastructure.
65
66
```java { .api }
67
/**
68
* Marker interface for instances that can bind/unbind groups of inputs and outputs.
69
*/
70
public interface Bindable {
71
72
/**
73
* Get the names of all inputs that can be bound.
74
* @return set of input names
75
*/
76
Set<String> getInputs();
77
78
/**
79
* Get the names of all outputs that can be bound.
80
* @return set of output names
81
*/
82
Set<String> getOutputs();
83
84
/**
85
* Create and bind all inputs using the provided binding service.
86
* @param bindingService the service to use for binding
87
* @return collection of created bindings
88
*/
89
Collection<Binding<Object>> createAndBindInputs(BindingService bindingService);
90
91
/**
92
* Create and bind all outputs using the provided binding service.
93
* @param bindingService the service to use for binding
94
* @return collection of created bindings
95
*/
96
Collection<Binding<Object>> createAndBindOutputs(BindingService bindingService);
97
98
/**
99
* Unbind all inputs.
100
*/
101
void unbindInputs();
102
103
/**
104
* Unbind all outputs.
105
*/
106
void unbindOutputs();
107
108
/**
109
* Bind all inputs using the provided binding service.
110
* @param bindingService the service to use for binding
111
*/
112
default void bindInputs(BindingService bindingService) {
113
createAndBindInputs(bindingService);
114
}
115
116
/**
117
* Bind all outputs using the provided binding service.
118
* @param bindingService the service to use for binding
119
*/
120
default void bindOutputs(BindingService bindingService) {
121
createAndBindOutputs(bindingService);
122
}
123
}
124
```
125
126
### Binding Target Factories
127
128
Factories for creating binding targets of different types.
129
130
```java { .api }
131
/**
132
* Factory for creating binding targets.
133
*/
134
public interface BindingTargetFactory {
135
136
/**
137
* Check if this factory can create the specified type of binding target.
138
* @param bindingTargetType the target type
139
* @return true if this factory can create the target type
140
*/
141
boolean canCreate(Class<?> bindingTargetType);
142
143
/**
144
* Create a binding target of the specified type.
145
* @param name the binding target name
146
* @param bindingTargetType the target type
147
* @param properties additional properties for target creation
148
* @return the created binding target
149
*/
150
Object createInput(String name, Class<?> bindingTargetType, Properties properties);
151
152
/**
153
* Create an output binding target of the specified type.
154
* @param name the binding target name
155
* @param bindingTargetType the target type
156
* @param properties additional properties for target creation
157
* @return the created binding target
158
*/
159
Object createOutput(String name, Class<?> bindingTargetType, Properties properties);
160
}
161
162
/**
163
* Factory for subscribable channel binding targets.
164
*/
165
public class SubscribableChannelBindingTargetFactory implements BindingTargetFactory, ApplicationContextAware {
166
167
public boolean canCreate(Class<?> bindingTargetType);
168
public MessageChannel createInput(String name, Class<?> bindingTargetType, Properties properties);
169
public MessageChannel createOutput(String name, Class<?> bindingTargetType, Properties properties);
170
public void setApplicationContext(ApplicationContext applicationContext);
171
}
172
173
/**
174
* Factory for message source binding targets.
175
*/
176
public class MessageSourceBindingTargetFactory implements BindingTargetFactory {
177
178
public boolean canCreate(Class<?> bindingTargetType);
179
public MessageSource<?> createInput(String name, Class<?> bindingTargetType, Properties properties);
180
public MessageSource<?> createOutput(String name, Class<?> bindingTargetType, Properties properties);
181
}
182
183
/**
184
* Factory for Flux message channel binding targets.
185
*/
186
public class FluxMessageChannelBindingTargetFactory implements BindingTargetFactory {
187
188
public boolean canCreate(Class<?> bindingTargetType);
189
public Object createInput(String name, Class<?> bindingTargetType, Properties properties);
190
public Object createOutput(String name, Class<?> bindingTargetType, Properties properties);
191
}
192
```
193
194
### Bindable Proxy Factories
195
196
Factories for creating bindable proxy objects.
197
198
```java { .api }
199
/**
200
* Base factory for creating bindable proxies.
201
*/
202
public abstract class AbstractBindableProxyFactory implements Bindable, BeanFactoryAware, ApplicationContextAware {
203
204
protected final Class<?> type;
205
protected BeanFactory beanFactory;
206
protected ApplicationContext applicationContext;
207
208
protected AbstractBindableProxyFactory(Class<?> type);
209
210
public Set<String> getInputs();
211
public Set<String> getOutputs();
212
public void bindInputs(BindingService bindingService);
213
public void bindOutputs(BindingService bindingService);
214
public void unbindInputs();
215
public void unbindOutputs();
216
217
protected abstract Object createBindableProxy();
218
219
public void setBeanFactory(BeanFactory beanFactory);
220
public void setApplicationContext(ApplicationContext applicationContext);
221
}
222
223
/**
224
* Factory for creating standard bindable proxies.
225
*/
226
public class BindableProxyFactory extends AbstractBindableProxyFactory {
227
228
public BindableProxyFactory(Class<?> type);
229
230
protected Object createBindableProxy();
231
public Object invoke(Object proxy, Method method, Object[] args);
232
}
233
```
234
235
### Message Channel Configurers
236
237
Interfaces and implementations for configuring message channels.
238
239
```java { .api }
240
/**
241
* Interface for configuring message channels.
242
*/
243
public interface MessageChannelConfigurer {
244
245
/**
246
* Configure the input channel.
247
* @param channel the channel to configure
248
* @param channelName the channel name
249
*/
250
void configureInputChannel(MessageChannel channel, String channelName);
251
252
/**
253
* Configure the output channel.
254
* @param channel the channel to configure
255
* @param channelName the channel name
256
*/
257
void configureOutputChannel(MessageChannel channel, String channelName);
258
}
259
260
/**
261
* Extended configurer for channels and sources.
262
*/
263
public interface MessageChannelAndSourceConfigurer extends MessageChannelConfigurer {
264
265
/**
266
* Configure a pollable message source.
267
* @param binding the binding target
268
* @param name the source name
269
* @param group the consumer group
270
*/
271
void configurePollableSource(Object binding, String name, String group);
272
}
273
274
/**
275
* Configurer for message converters.
276
*/
277
public class MessageConverterConfigurer implements MessageChannelConfigurer, BeanFactoryAware {
278
279
public void configureInputChannel(MessageChannel channel, String channelName);
280
public void configureOutputChannel(MessageChannel channel, String channelName);
281
public void setBeanFactory(BeanFactory beanFactory);
282
}
283
284
/**
285
* Composite configurer that delegates to multiple configurers.
286
*/
287
public class CompositeMessageChannelConfigurer implements MessageChannelConfigurer {
288
289
private final List<MessageChannelConfigurer> configurers;
290
291
public CompositeMessageChannelConfigurer(List<MessageChannelConfigurer> configurers);
292
293
public void configureInputChannel(MessageChannel channel, String channelName);
294
public void configureOutputChannel(MessageChannel channel, String channelName);
295
}
296
```
297
298
### Binding Lifecycle Management
299
300
Classes for managing binding lifecycle events and states.
301
302
```java { .api }
303
/**
304
* Base class for binding lifecycle management.
305
*/
306
public abstract class AbstractBindingLifecycle implements SmartLifecycle, ApplicationContextAware {
307
308
protected ApplicationContext applicationContext;
309
protected volatile boolean running;
310
311
public void start();
312
public void stop();
313
public boolean isRunning();
314
public int getPhase();
315
public boolean isAutoStartup();
316
public void stop(Runnable callback);
317
318
public void setApplicationContext(ApplicationContext applicationContext);
319
320
protected abstract void doStartWithBindingService(BindingService bindingService);
321
protected abstract void doStopWithBindingService(BindingService bindingService);
322
}
323
324
/**
325
* Lifecycle management for input bindings.
326
*/
327
public class InputBindingLifecycle extends AbstractBindingLifecycle {
328
329
private final Bindable bindable;
330
private final Collection<String> inputNames;
331
332
public InputBindingLifecycle(Bindable bindable, Collection<String> inputNames);
333
334
protected void doStartWithBindingService(BindingService bindingService);
335
protected void doStopWithBindingService(BindingService bindingService);
336
}
337
338
/**
339
* Lifecycle management for output bindings.
340
*/
341
public class OutputBindingLifecycle extends AbstractBindingLifecycle {
342
343
private final Bindable bindable;
344
private final Collection<String> outputNames;
345
346
public OutputBindingLifecycle(Bindable bindable, Collection<String> outputNames);
347
348
protected void doStartWithBindingService(BindingService bindingService);
349
protected void doStopWithBindingService(BindingService bindingService);
350
}
351
352
/**
353
* Controller for managing bindings lifecycle.
354
*/
355
public class BindingsLifecycleController implements ApplicationContextAware {
356
357
private ApplicationContext applicationContext;
358
359
/**
360
* Change the state of a binding.
361
* @param name the binding name
362
* @param state the desired state
363
*/
364
public void changeState(String name, State state);
365
366
/**
367
* Query the states of all bindings.
368
* @return map of binding states keyed by name
369
*/
370
public Map<String, List<BindingInformation>> queryStates();
371
372
/**
373
* Query the state of a specific binding.
374
* @param name the binding name
375
* @return list of binding information for the named binding
376
*/
377
public List<BindingInformation> queryState(String name);
378
379
public void setApplicationContext(ApplicationContext applicationContext);
380
381
/**
382
* Information about a binding's current state.
383
*/
384
public static class BindingInformation {
385
private final String bindingName;
386
private final State state;
387
private final String group;
388
private final boolean pausable;
389
390
public BindingInformation(String bindingName, State state, String group, boolean pausable);
391
392
public String getBindingName();
393
public State getState();
394
public String getGroup();
395
public boolean isPausable();
396
}
397
}
398
```
399
400
### Destination Binding Callbacks
401
402
Callbacks for handling new destination binding events.
403
404
```java { .api }
405
/**
406
* Callback interface for new destination binding configuration.
407
* @param <T> the binding target type
408
*/
409
public interface NewDestinationBindingCallback<T> {
410
411
/**
412
* Configure a new destination binding.
413
* @param channelName the channel name
414
* @param channel the channel being bound
415
* @param producerProperties producer properties for the binding
416
* @param extendedProducerProperties extended producer properties
417
*/
418
void configure(String channelName, T channel, ProducerProperties producerProperties, Object extendedProducerProperties);
419
}
420
```
421
422
### Partitioning Support
423
424
Channel interceptor for handling message partitioning.
425
426
```java { .api }
427
/**
428
* Channel interceptor for partitioning messages.
429
*/
430
public class DefaultPartitioningInterceptor implements ChannelInterceptor, BeanFactoryAware {
431
432
private BeanFactory beanFactory;
433
434
/**
435
* Intercept message sending to add partition information.
436
* @param message the message being sent
437
* @param channel the channel
438
* @return the message with partition information added
439
*/
440
public Message<?> preSend(Message<?> message, MessageChannel channel);
441
442
public void setBeanFactory(BeanFactory beanFactory);
443
}
444
```
445
446
### Utility Classes
447
448
Utility classes for binding management operations.
449
450
```java { .api }
451
/**
452
* Defines supported bindable features.
453
*/
454
public class SupportedBindableFeatures {
455
456
private boolean synchronousConsumer = false;
457
private boolean pollableConsumer = false;
458
private boolean routeToDlq = false;
459
460
public boolean isSynchronousConsumer();
461
public void setSynchronousConsumer(boolean synchronousConsumer);
462
463
public boolean isPollableConsumer();
464
public void setPollableConsumer(boolean pollableConsumer);
465
466
public boolean isRouteToDlq();
467
public void setRouteToDlq(boolean routeToDlq);
468
}
469
470
/**
471
* Router that is aware of binder configuration.
472
*/
473
public class BinderAwareRouter extends AbstractMappingMessageRouter implements ApplicationContextAware {
474
475
private ApplicationContext applicationContext;
476
477
protected String getChannelKey(Message<?> message);
478
public void setApplicationContext(ApplicationContext applicationContext);
479
}
480
481
/**
482
* Listener for context start after refresh events.
483
*/
484
public class ContextStartAfterRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
485
486
public void onApplicationEvent(ContextRefreshedEvent event);
487
}
488
```
489
490
**Usage Examples:**
491
492
```java
493
import org.springframework.cloud.stream.binding.*;
494
import org.springframework.integration.channel.DirectChannel;
495
import org.springframework.messaging.MessageChannel;
496
import org.springframework.context.annotation.Bean;
497
import org.springframework.context.annotation.Configuration;
498
499
// Creating a bindable service
500
@Component
501
public class MyMessageService implements Bindable {
502
503
private final Map<String, MessageChannel> inputs = new HashMap<>();
504
private final Map<String, MessageChannel> outputs = new HashMap<>();
505
506
@Override
507
public Set<String> getInputs() {
508
return inputs.keySet();
509
}
510
511
@Override
512
public Set<String> getOutputs() {
513
return outputs.keySet();
514
}
515
516
@Override
517
public void bindInputs(BindingService bindingService) {
518
for (Map.Entry<String, MessageChannel> entry : inputs.entrySet()) {
519
bindingService.bindConsumer(entry.getValue(), entry.getKey());
520
}
521
}
522
523
@Override
524
public void bindOutputs(BindingService bindingService) {
525
for (Map.Entry<String, MessageChannel> entry : outputs.entrySet()) {
526
bindingService.bindProducer(entry.getValue(), entry.getKey());
527
}
528
}
529
530
@Override
531
public void unbindInputs() {
532
// Implementation for unbinding inputs
533
}
534
535
@Override
536
public void unbindOutputs() {
537
// Implementation for unbinding outputs
538
}
539
540
public void addInput(String name, MessageChannel channel) {
541
inputs.put(name, channel);
542
}
543
544
public void addOutput(String name, MessageChannel channel) {
545
outputs.put(name, channel);
546
}
547
}
548
549
// Using BindingService directly
550
@Service
551
public class DynamicBindingService {
552
553
private final BindingService bindingService;
554
555
public DynamicBindingService(BindingService bindingService) {
556
this.bindingService = bindingService;
557
}
558
559
public void createDynamicConsumer(String inputName) {
560
MessageChannel channel = new DirectChannel();
561
channel.subscribe(message -> {
562
System.out.println("Received: " + message.getPayload());
563
});
564
565
Collection<Binding<Object>> bindings = bindingService.bindConsumer(channel, inputName);
566
// Store bindings for later cleanup if needed
567
}
568
569
public void createDynamicProducer(String outputName) {
570
MessageChannel channel = new DirectChannel();
571
Binding<MessageChannel> binding = bindingService.bindProducer(channel, outputName);
572
573
// Now you can send messages through this channel
574
channel.send(MessageBuilder.withPayload("Hello World").build());
575
}
576
}
577
578
// Custom channel configurer
579
@Component
580
public class CustomChannelConfigurer implements MessageChannelConfigurer {
581
582
@Override
583
public void configureInputChannel(MessageChannel channel, String channelName) {
584
if (channel instanceof AbstractMessageChannel) {
585
AbstractMessageChannel abstractChannel = (AbstractMessageChannel) channel;
586
// Add custom interceptors
587
abstractChannel.addInterceptor(new MyCustomInterceptor());
588
}
589
}
590
591
@Override
592
public void configureOutputChannel(MessageChannel channel, String channelName) {
593
if (channel instanceof AbstractMessageChannel) {
594
AbstractMessageChannel abstractChannel = (AbstractMessageChannel) channel;
595
// Add custom interceptors for output
596
abstractChannel.addInterceptor(new MyOutputInterceptor());
597
}
598
}
599
}
600
601
// Managing binding lifecycle
602
@Component
603
public class BindingController {
604
605
private final BindingsLifecycleController lifecycleController;
606
607
public BindingController(BindingsLifecycleController lifecycleController) {
608
this.lifecycleController = lifecycleController;
609
}
610
611
public void pauseBinding(String bindingName) {
612
lifecycleController.changeState(bindingName, State.PAUSED);
613
}
614
615
public void resumeBinding(String bindingName) {
616
lifecycleController.changeState(bindingName, State.RESUMED);
617
}
618
619
public void stopBinding(String bindingName) {
620
lifecycleController.changeState(bindingName, State.STOPPED);
621
}
622
623
public Map<String, List<BindingsLifecycleController.BindingInformation>> getAllBindingStates() {
624
return lifecycleController.queryStates();
625
}
626
}
627
```