The performance is degrading just because you give more and more beans for the application context on each flow registration. And each new flow needs to recheck existing beans to avoid duplication error, so we will try to reuse as much beans as possible.
I understand your concern about different beans and redundant scanning procedure, but how can we know that on the bean registration that this is new object or you try to inject an existing one?
To improve some parallel registration performance, consider to set a unique id for those dynamic flows. See its builder API:
/**
* Specify an {@code id} for the {@link IntegrationFlow} to register.
* Must be unique per context.
* The registration with this {@code id} must be destroyed before reusing for
* a new {@link IntegrationFlow} instance.
* @param id the id for the {@link IntegrationFlow} to register
* @return the current builder instance
*/
IntegrationFlowRegistrationBuilder id(String id);
This way the lock is not used to synchronize on bean registrations and they can be created concurrently.
UPDATE
I looked into the code and probably a culprit is here:
return !this.beanFactory.getBeansOfType(instance.getClass(), false, false)
.values()
.contains(instance);
On every bean you trying to add which is not a NamedComponent
or comes without a beanName
. Consider to add explicit id
to all the endpoints you declare in your flows. Something like this:
.<String, String>transform(String::toUpperCase, e -> e.id(flowId + ".transformer"))
I'm thinking about possible optimization for this kind of registrations when we add an implicit bean names to those unnamed components...
Please, raise a GitHub issue and we will think together what and how could be improved: https://github.com/spring-projects/spring-integration/issues