From 3a396ef98427cab5ca63da2479573b603658fd57 Mon Sep 17 00:00:00 2001 From: Tran Ngoc Nhan Date: Mon, 31 Aug 2026 18:22:37 +0700 Subject: [PATCH] Polish producing-and-consuming-messages.adoc - Fix typos - Update reference links - Update source block with language attribute Signed-off-by: Tran Ngoc Nhan --- .../producing-and-consuming-messages.adoc | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/modules/ROOT/pages/spring-cloud-stream/producing-and-consuming-messages.adoc b/docs/modules/ROOT/pages/spring-cloud-stream/producing-and-consuming-messages.adoc index 8c533353a1..f5eccf3f8b 100644 --- a/docs/modules/ROOT/pages/spring-cloud-stream/producing-and-consuming-messages.adoc +++ b/docs/modules/ROOT/pages/spring-cloud-stream/producing-and-consuming-messages.adoc @@ -294,7 +294,7 @@ will go through the same routine when sending output as if it was from any Funct of consistency as with functions. This means the output type conversion, partitioning etc are honored as if it was from the output produced by functions. IMPORTANT: Unlike it is explained in xref:spring-cloud-stream/explicit-binding-creation.adoc[Explicit Binding Creation], _StreamBridge_ was designed with both performance in mind and ability to create as many bindings on the fly as necessary. To achieve that the actual bindings created by the _StreamBridge_ are not cached in the application context and therefore can not be managed as explained in xref:spring-cloud-stream/binding_visualization_control.adoc[Binding visualization and control]. -However if it is still your desire to use _StreamBridge_ to create bindings dynamically and manage them after, please use the following mechanism to create binding explicitly before using _StreamBridge_ - ref:spring-cloud-stream/binding_visualization_control.adocl#_define_new_and_manage_existing_bindings[Define New Binding Programmatically] +However if it is still your desire to use _StreamBridge_ to create bindings dynamically and manage them after, please use the following mechanism to create binding explicitly before using _StreamBridge_ - xref:spring-cloud-stream/binding_visualization_control.adoc#_define_new_and_manage_existing_bindings[Define New Binding Programmatically] @@ -383,7 +383,7 @@ the dynamic features of `StreamBridge` where if `myBinding` doesn't exist it wil NOTE: Caching dynamic destinations (bindings) could result in memory leaks in the event there are many dynamic destinations. To have some level of control we provide a self-evicting caching mechanism for output bindings with default cache size of 10. This means that if your dynamic destination size goes above that number, there is a possibility that an existing binding will be evicted and thus would need to be recreated which could cause minor performance degradation. You can increase the cache size via `spring.cloud.stream.dynamic-destination-cache-size` property setting it to the desired value. - +[source,bash] ---- curl -H "Content-Type: text/plain" -X POST -d "hello from the other side" http://localhost:8080/ ---- @@ -405,19 +405,19 @@ Spring Cloud Stream supports multiple binder scenarios. For example you may be r For more information on multiple binders scenarios, please see xref:spring-cloud-stream/binders.adoc#binders[Binders] section and specifically xref:spring-cloud-stream/multiple-binders.adoc#multiple-binders[Multiple Binders on the Classpath] -In the event you are planning to use StreamBridge and have more then one binder configured in your application you must also tell StreamBridge +In the event you are planning to use StreamBridge and have more than one binder configured in your application you must also tell StreamBridge which binder to use. And for that there are two more variations of `send` method: [source, java] ---- -public boolean send(String bindingName, @Nullable String binderType, Object data) +public boolean send(String bindingName, @Nullable String binderName, Object data); -public boolean send(String bindingName, @Nullable String binderType, Object data, MimeType outputContentType) +public boolean send(String bindingName, @Nullable String binderName, Object data, MimeType outputContentType); ---- -As you can see there is one additional argument that you can provide - `binderType`, telling BindingService which binder to use when creating dynamic binding. +As you can see there is one additional argument that you can provide - `binderName`, telling BindingService which binder to use when creating dynamic binding. -NOTE: For cases where `spring.cloud.stream.output-bindings` property is used or the binding was already created under different binder, the `binderType` +NOTE: For cases where `spring.cloud.stream.output-bindings` property is used or the binding was already created under different binder, the `binderName` argument will have no effect. [[using-channel-interceptors-with-streambridge]] @@ -425,7 +425,7 @@ argument will have no effect. Since `StreamBridge` uses a `MessageChannel` to establish the output binding, you can activate channel interceptors when sending data through `StreamBridge`. It is up to the application to decide which channel interceptors to apply on `StreamBridge`. -Spring Cloud Stream does not inject all the channel interceptors detected into `StreamBridge` unless they are annoatated with `@GlobalChannelInterceptor(patterns = "*")`. +Spring Cloud Stream does not inject all the channel interceptors detected into `StreamBridge` unless they are annotated with `@GlobalChannelInterceptor(patterns = "*")`. Let us assume that you have the following two different `StreamBridge` bindings in the application. @@ -437,7 +437,8 @@ and Now, if you want a channel interceptor applied on both the `StreamBridge` bindings, then you can declare the following `GlobalChannelInterceptor` bean. -``` +[source,java] +---- @Bean @GlobalChannelInterceptor(patterns = "*") public ChannelInterceptor customInterceptor() { @@ -448,11 +449,12 @@ public ChannelInterceptor customInterceptor() { } }; } -``` +---- However, if you don't like the global approach above and want to have a dedicated interceptor for each binding, then you can do the following. -``` +[source,java] +---- @Bean @GlobalChannelInterceptor(patterns = "foo-*") public ChannelInterceptor fooInterceptor() { @@ -463,11 +465,12 @@ public ChannelInterceptor fooInterceptor() { } }; } -``` +---- and -``` +[source,java] +---- @Bean @GlobalChannelInterceptor(patterns = "bar-*") public ChannelInterceptor barInterceptor() { @@ -478,7 +481,7 @@ public ChannelInterceptor barInterceptor() { } }; } -``` +---- You have the flexibility to make the patterns more strict or customized to your business needs. @@ -540,7 +543,7 @@ public Function wrapInQuotes() { and modify the `spring.cloud.function.definition` property to reflect your intention to compose a new function from both ‘toUpperCase’ and ‘wrapInQuotes’. To do so Spring Cloud Function relies on `|` (pipe) symbol. So, to finish our example our property will now look like this: -[source,java] +[source,properties] ---- --spring.cloud.function.definition=toUpperCase|wrapInQuotes ---- @@ -668,6 +671,7 @@ output binding also follows the same convention and is named `gather-out-0`. Knowing that will allow you to set binding specific properties. For example, the following will override content-type for `gather-in-0` binding: +[source,properties] ---- --spring.cloud.stream.bindings.gather-in-0.content-type=text/plain ---- @@ -693,7 +697,7 @@ public class SampleApplication { } ---- -The above example is somewhat of a the opposite from the previous sample and demonstrates function which +The above example is somewhat of the opposite from the previous sample and demonstrates function which takes single input of type `Integer` and produces two outputs (both of type `String`). So, for the above example the input binding is `scatter-in-0` and the @@ -751,12 +755,12 @@ public class SampleApplication { ---- In the above example we have configuration which defines two functions `uppercase` and `reverse`. -So first, as mentioned before, we need to notice that there is a a conflict (more then one function) and therefore +So first, as mentioned before, we need to notice that there is a conflict (more than one function) and therefore we need to resolve it by providing `spring.cloud.function.definition` property pointing to the actual function we want to bind. Except here we will use `;` delimiter to point to both functions (see test case below). -IMPORTANT: As with functions with multiple inputs/outputs, please refer to <> section to understand the naming +IMPORTANT: As with functions with multiple inputs/outputs, please refer to xref:spring-cloud-stream/binding-names.adoc[Binding and Binding names] section to understand the naming convention used to establish _binding names_ used by such application. And you test it with the following code: @@ -878,7 +882,7 @@ of https://www.enterpriseintegrationpatterns.com[Enterprise Integration Patterns framework such as https://spring.io/projects/spring-integration[Spring Integration] (SI), which is a reference implementation of EIP. Thankfully SI already provides support for exposing integration flows as functions via -https://docs.spring.io/spring-integration/docs/current/reference/html/#java-dsl-gateway[Integration flow as gateway] +https://docs.spring.io/spring-integration/reference/dsl/integration-flow-as-gateway.html[Integration flow as gateway] Consider the following sample: [source, java] @@ -914,7 +918,7 @@ To receive raw input you can use `from(Function.class, ...)`. The resulting function is bound to the input and output destinations exposed by the target binder. -IMPORTANT: Please refer to <> section to understand the naming +IMPORTANT: Please refer to xref:spring-cloud-stream/binding-names.adoc[Binding and Binding names] section to understand the naming convention used to establish _binding names_ used by such application. For more details on interoperability of Spring Integration and Spring Cloud Stream specifically around functional programming model @@ -933,7 +937,7 @@ To define binding for polled consumer you need to provide `spring.cloud.stream.p Consider the following example of a polled consumer binding: -[source,text] +[source,properties] ---- --spring.cloud.stream.pollable-source=myDestination ---- @@ -1018,7 +1022,7 @@ There is also an overloaded `poll` method, for which the definition is as follow [source,java] ---- -poll(MessageHandler handler, ParameterizedTypeReference type) +boolean poll(MessageHandler handler, ParameterizedTypeReference type); ---- The `type` is a conversion hint that allows the incoming message payload to be converted, as shown in the following example: