Spring Integration 5.1 - 使用 @IntegrationConverter 的集成流转换不起作用

Posted

技术标签:

【中文标题】Spring Integration 5.1 - 使用 @IntegrationConverter 的集成流转换不起作用【英文标题】:Spring Integration 5.1 - integration flow convertion with @IntegrationConverter doesn't work 【发布时间】:2020-01-14 13:43:57 【问题描述】:

我将我的 Spring boot 版本从 2.0.5.RELEASE 升级到 2.1.8.RELEASE(因此 Spring Integration 从 5.0 升级到 5.1)并且集成流中的自动类型转换不再起作用。我习惯于在集成流代码中定义一组@IntegrationConverter 组件并使用操作transform(Type.class, p -> p) 进行自动转换,但在新版本中它似乎被破坏了。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.grorg</groupId>
    <artifactId>grointegration</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>grointegration</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-ip</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

还有 Main.java 文件:

package org.grorg.grointegration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.convert.converter.Converter;
import org.springframework.integration.config.IntegrationConverter;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.Transformers;
import org.springframework.integration.ip.dsl.Tcp;
import org.springframework.stereotype.Component;

class Test 
    @Override
    public String toString() 
        return "test";
    


@Component
@IntegrationConverter
class Convert implements Converter<String, Test> 
    @Override
    public Test convert(String s) 
        return new Test();
    


@SpringBootApplication
public class Main 

    public static void main(String[] args) 
        SpringApplication.run(GrointegrationApplication.class, args);
    

    @Bean
    public IntegrationFlow server() 
        return IntegrationFlows
                .from(Tcp.inboundGateway(Tcp.netServer(1234)))
                .transform(Transformers.objectToString())
                .transform(Test.class, id -> id) // in 2.1 I could use .convert(Test.class) but the problem is the same
                .log()
                .handle((p, h) -> "OK")
                .get();
    

与外壳一起使用:

telnet localhost 1234
> test
> OK
[...]

使用以前的版本 (2.0.5.RELEASE) 程序可以像以前一样正常工作,但是使用新版本 (2.1.8.RELEASE) 我收到此错误(并且没有“OK”响应):

org.springframework.integration.handler.ReplyRequiredException: No reply produced by handler 'server.org.springframework.integration.config.ConsumerEndpointFactoryBean#1', and its 'requiresReply' property is set to true.
[...]

我发现ConversionService 已被MessageConverter 替换,现在Jackson 用于将消息从一种类型转换为另一种类型。

我是否错误地将类型转换与集成流结合使用?您有使用新版本投射对象的新解决方案吗?或者这只是一种回归?

提前致谢!

【问题讨论】:

让我在本地玩这个!我将使用您的配置生成一些 Spring Boot 项目... 【参考方案1】:

这是 Spring Integration 中的一个错误。 我们只是没有在GenericMessageConverter 中使用正确的ConversionService

请就此事提出 GH 问题。

同时,您的解决方法如下:

@Bean(name = IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME)
public static ConfigurableCompositeMessageConverter configurableCompositeMessageConverter(
        @Qualifier(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME) ConversionService conversionService) 
    return new ConfigurableCompositeMessageConverter(
            Collections.singleton(new GenericMessageConverter(conversionService)));

因此,我们覆盖框架配置的任何内容,并注入一个适当的 IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME bean,该 bean 与您的 @IntegrationConverter 组件一起提供。

【讨论】:

非常感谢,我按照你的建议打开了github问题:github.com/spring-projects/spring-integration/issues/3052

以上是关于Spring Integration 5.1 - 使用 @IntegrationConverter 的集成流转换不起作用的主要内容,如果未能解决你的问题,请参考以下文章

spring integration:如何从 Spring Controller 调用 Spring Integration?

MyBatis(3.2.3) - Integration with Spring

INTEGRATION TESTING WITH SPRING AND JUNIT

Spring Integration Dispatcher 没有频道订阅者

使用 Spring Integration HttpInbound 示例

spring-integration-file 的 junit 测试用例