Search code examples
javaspringspring-integrationspring-xdspring-el

How to use Spring XD Module Options in SpEL expression of Spring Integration DSL?


I'm implementing a custom Spring XD module (processor). I've added Module Options to it, they can be easily referenced in ModuleConfiguration via @Value("${varName}") syntax.

However, I can't use them directly in SpEL expressions of the flow builder:

return IntegrationFlows
            .from(input)
            .enrichHeaders(h -> h
                    .headerExpression("varHeader", "varName") //That's the line with an issue
            )
            .transform(customTransformer)
            .channel(output)
            .get();

Is there a way to use the directly in the flow builder, not injecting into the configuration bean?


Solution

  • It's not a problem of Spring XD, neither Spring Integration Java DSL or even just Java & Annotation Configuration.

    The difference between Java Config and XML config (in this case), that the properties for XML bean definitions undergo an additions transformation phase - BeanDefinition properties merge. It is helpful for the target object creation.

    With that you can define your expression property with the Property Placeholder value to be extracted before the targeg object creation.

    Right, with Java Config we have the BeanDefinition as well, but with Java Config the object instantiation is fully in your hands. Therefore any set...() is out of Container scope and it can't determine that your value is with Property Placeholder.

    The Java & Annotation Configuration suggests to use @Value("${varName}") and use the value directly in your @Bean method. From other side you even can move that annotation to the method definition:

    @Bean
    public IntegrationFlow myFlow(@Value("${varName}") String myValue) {
    .....
    }
    

    There is another trick, which won't be so elegant for because it is a bit verbose:

    .headerExpression("varHeader", "@environment.getProperty('varName')") 
    

    The Environment to resolve Property Placeholders is exposed as a bean and any Spring Integration Expressions have access to bean factory. Only bottleneck that this Expression will be evaluated for each message, not once like it is in case of @Value("${varName}").