无法在 spring-integration 4 中将字符串值转换为 ExpressionEvaluatingRequestHandlerAdvice 的表达式。1.x

Cannot convert String value to Expression for ExpressionEvaluatingRequestHandlerAdvice in spring-integration 4.1.x

我无法让 ExpressionEvaluatingRequestHandlerAdvice class 在 Spring Integration 4.1.x 中工作。以下表达式建议上下文 XML 片段产生一个转换错误,指出 Spring 无法将属性 onSuccessExpression 转换为字符串中的表达式。在 Spring Integration 4.1.0-RELEASE 之前,setOnSuccessExpression() 方法只接受字符串,现在它被重载以接受字符串或表达式。

<sftp:outbound-channel-adapter channel="outboundChannel"
    session-factory="sftpCachingSessionFactory" remote-directory="${sftp.remote.file.location.path}"
    temporary-file-suffix=".tmp">
    <sftp:request-handler-advice-chain>
        <bean
            class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
            <property name="retryTemplate" ref="defaultRetryTemplate" />
        </bean>
        <bean
            class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="headers.ID" />
            <property name="successChannel" ref="outboundSuccessChannel" />
        </bean>
    </sftp:request-handler-advice-chain>
</sftp:outbound-channel-adapter>

以下是显示的错误:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.file.config.FileWritingMessageHandlerFactoryBean#0': Cannot resolve reference to bean 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#7d12855' while setting bean property 'adviceChain' with key [1]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#7d12855' defined in class path resource [file-transfer-service-file-endpoint-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onSuccessExpression'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.expression.Expression] for property 'onSuccessExpression': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:382)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:157)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1469)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:743)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at pmd.common.spring.SpringServiceContextLoader.main(SpringServiceContextLoader.java:63)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice#7d12855' defined in class path resource [file-transfer-service-file-endpoint-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onSuccessExpression'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.expression.Expression] for property 'onSuccessExpression': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
    ... 15 more
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onSuccessExpression'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.expression.Expression] for property 'onSuccessExpression': no matching editors or conversion strategy found
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:475)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:511)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:505)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1515)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1474)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    ... 21 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.expression.Expression] for property 'onSuccessExpression': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:287)
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:460)
    ... 27 more

我的问题是我认为我的 onSuccessExpression 不应该被转换,setOnSuccessExpression() 方法上有一个字符串设置器。我有修复程序还是 Spring Int 造成了错误?

这是一个错误;我们添加了第二组设置器来支持 DSL(因此您可以注入字符串或表达式)。

问题是违反了 JavaBean 定义(2 个具有不同参数类型的 setter),因此 Spring 不知道该选择哪一个。我们需要更改方法名称。

遗憾的是,无法确定 Spring 调用了哪个方法。

同时,您可以尝试使用此解决方法...

<bean id="success" class="org.springframework.integration.config.ExpressionFactoryBean">
    <constructor-arg value="headers.ID" />
</bean>

和...

<property name="onSuccessExpression" ref="success" />

不幸的是,调用哪个方法是不确定的;在我的环境中,您的代码可以工作,因为选择了该方法的字符串版本。

因此,如果您 运行 在多个环境中,您可能必须将建议作为 @Bean 连接起来作为解决方法。

我开了一个JIRA Issue。我们将很快在一个版本中得到修复。