INT-4473: Support prefix bean names with flow id
JIRA: https://jira.spring.io/browse/INT-4473 Previously, dynamic registration of integration flows with components configured with the same `id` would fail with duplicate bean names. Add `useFlowIdAsPrefix()` to the registration builder to enable the option. Then, in the BPP, check the flag before naming the beans. **cherry-pick to 5.0.x** * Polishing according PR comments * Widen `flowNamePrefix` responsibility in the `IntegrationFlowBeanPostProcessor` since we may have many other components in the dynamic flow with the same id, not only consumer endpoints # Conflicts: # spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java # spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowContext.java # spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java # src/reference/asciidoc/dsl.adoc
This commit is contained in:
committed by
Artem Bilan
parent
d0603a80ff
commit
48df4f211c
@@ -578,7 +578,7 @@ The result of this definition is the same bunch of Integration components wired
|
||||
Only limitation is here, that this flow is started with named direct channel - `lambdaFlow.input`.
|
||||
And Lambda flow can't start from `MessageSource` or `MessageProducer`.
|
||||
|
||||
Starting with _version 5.0.5_, the generated bean names for the components in an `IntegrationFlow` include the flow bean followed by a dot as a prefix.
|
||||
Starting with _version 5.0.6_, the generated bean names for the components in an `IntegrationFlow` include the flow bean followed by a dot as a prefix.
|
||||
For example the `ConsumerEndpointFactoryBean` for the `.transform("Hello "::concat)` in the sample above, will end up with te bean name like `lambdaFlow.org.springframework.integration.config.ConsumerEndpointFactoryBean#0`.
|
||||
The `Transformer` implementation bean for that endpoint will have a bean name such as `lambdaFlow.org.springframework.integration.transformer.MethodInvokingTransformer#0`.
|
||||
These generated bean names are prepended with the flow id prefix for purposes such as parsing logs or grouping components together in some analysis tool, as well as to avoid a race condition when we concurrently register integration flows at runtime.
|
||||
@@ -895,10 +895,46 @@ Usually those additional beans are connection factories (AMQP, JMS, (S)FTP, TCP/
|
||||
Such a dynamically registered `IntegrationFlow` and all its dependant beans can be removed afterwards using `IntegrationFlowRegistration.destroy()` callback.
|
||||
See `IntegrationFlowContext` JavaDocs for more information.
|
||||
|
||||
NOTE: Starting with _version 5.0.5_, all generated bean names in an `IntegrationFlow` definition are prepended with flow id as a prefix.
|
||||
NOTE: Starting with _version 5.0.6_, all generated bean names in an `IntegrationFlow` definition are prepended with flow id as a prefix.
|
||||
It is recommended to always specify an explicit flow id, otherwise a synchronization barrier is initiated in the `IntegrationFlowContext` to generate the bean name for the `IntegrationFlow` and register its beans.
|
||||
We synchronize on these two operations to avoid a race condition when the same generated bean name may be used for different `IntegrationFlow` instances.
|
||||
|
||||
Also, starting with _version 5.0.6_, the registration builder API has a new method `useFlowIdAsPrefix()`.
|
||||
This is useful if you wish to declare multiple instances of the same flow and avoid bean name collisions if components in the flows have the same id.
|
||||
|
||||
For example:
|
||||
|
||||
[source, java]
|
||||
----
|
||||
private void registerFlows() {
|
||||
IntegrationFlowRegistration flow1 =
|
||||
this.flowContext.registration(buildFlow(1234))
|
||||
.id("tcp1")
|
||||
.useFlowIdAsPrefix()
|
||||
.register();
|
||||
|
||||
IntegrationFlowRegistration flow2 =
|
||||
this.flowContext.registration(buildFlow(1235))
|
||||
.id("tcp2")
|
||||
.useFlowIdAsPrefix()
|
||||
.register();
|
||||
}
|
||||
|
||||
private IntegrationFlow buildFlow(int port) {
|
||||
return f -> f
|
||||
.handle(Tcp.outboundGateway(Tcp.netClient("localhost", port)
|
||||
.serializer(TcpCodecs.crlf())
|
||||
.deserializer(TcpCodecs.lengthHeader1())
|
||||
.id("client"))
|
||||
.remoteTimeout(m -> 5000))
|
||||
.transform(Transformers.objectToString());
|
||||
}
|
||||
----
|
||||
|
||||
In this case, the message handler for the first flow can be referenced with bean name `tcp1.client.handler`.
|
||||
|
||||
NOTE: an `id` is required when using `useFlowIdAsPrefix()`.
|
||||
|
||||
[[java-dsl-gateway]]
|
||||
=== IntegrationFlow as Gateway
|
||||
|
||||
|
||||
Reference in New Issue
Block a user