diff --git a/docs/src/main/asciidoc/spring-cloud-stream.adoc b/docs/src/main/asciidoc/spring-cloud-stream.adoc index db152117a..e74f8ced7 100644 --- a/docs/src/main/asciidoc/spring-cloud-stream.adoc +++ b/docs/src/main/asciidoc/spring-cloud-stream.adoc @@ -380,6 +380,9 @@ you must provide `spring.cloud.function.definition` property. NOTE: In the event you only have single bean of type `java.util.function.[Supplier/Function/Consumer]`, you can skip the `spring.cloud.function.definition` property, since such functional bean will be auto-discovered. However, it is considered best practice to use such property to avoid any confusion. +Some time this auto-discovery can get in the way, since single bean of type `java.util.function.[Supplier/Function/Consumer]` +could be there for purposes other then handling messages, yet being single it is auto-discovered and auto-bound. +For these rare scenarios you can disable auto-discovery by providing `spring.cloud.stream.function.autodetect` property with value set to `false`. Here is the example of the application exposing message handler as `java.util.function.Function` effectively supporting _pass-thru_ semantics by acting as consumer and producer of data. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java index cbec4d996..3f97512a1 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java @@ -871,6 +871,7 @@ public class FunctionConfiguration { } private boolean determineFunctionName(FunctionCatalog catalog, Environment environment) { + boolean autodetect = environment.getProperty("spring.cloud.stream.function.autodetect", boolean.class, true); String definition = streamFunctionProperties.getDefinition(); if (!StringUtils.hasText(definition)) { definition = environment.getProperty("spring.cloud.function.definition"); @@ -883,7 +884,7 @@ public class FunctionConfiguration { || environment.containsProperty("spring.cloud.function.routing-expression")) { streamFunctionProperties.setDefinition(RoutingFunction.FUNCTION_NAME); } - else { + else if (autodetect) { streamFunctionProperties.setDefinition(((FunctionInspector) functionCatalog).getName(functionCatalog.lookup(""))); } return StringUtils.hasText(streamFunctionProperties.getDefinition()); diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java index a9b3ba9af..9e67b1245 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java @@ -81,6 +81,23 @@ public class ImplicitFunctionBindingTests { System.clearProperty("spring.cloud.function.definition"); } + @SuppressWarnings({"rawtypes" }) + @Test + public void testDisableAutodetect() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false", "--spring.cloud.stream.function.autodetect=false")) { + + BindingsLifecycleController ctrl = context.getBean(BindingsLifecycleController.class); + Binding input = ctrl.queryState("echo-in-0"); + Binding output = ctrl.queryState("echo-out-0"); + assertThat(input).isNull(); + assertThat(output).isNull(); + } + } + + @SuppressWarnings({"rawtypes" }) @Test public void testBindingControl() { @@ -216,7 +233,9 @@ public class ImplicitFunctionBindingTests { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class)) .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func|addHeaders")) { + .run("--spring.jmx.enabled=false", + "--spring.cloud.stream.function.autodetect=false", + "--spring.cloud.function.definition=func|addHeaders")) { InputDestination inputDestination = context.getBean(InputDestination.class); OutputDestination outputDestination = context.getBean(OutputDestination.class);