【问题标题】:Unable to autowire MessageChannel in Spring Integration无法在 Spring 集成中自动装配 MessageChannel
【发布时间】:2017-02-05 16:04:34
【问题描述】:

我正在尝试使用 spring 集成的 FTP 文件上传和下载示例。我想手动将文件上传到 outputChannel。当 inputChannel 发生变化时,我不想调用它。因此,FTPApplication 应该只有一个 outputChannel bean 的声明。为此,我参考了这篇文章Uploading files directly to specific folder in ftp server using spring spring(仅用于手动上传,这种方式在大多数页面中都很常见)。下面是 Spring Boot 应用代码:

@SpringBootApplication
public class FtpApplication {

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

    @Bean
    public SessionFactory<FTPFile> ftpSessionFactory() {
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost("localhost");
        sf.setPort(21);
        sf.setUsername("root");
        sf.setPassword("root");
        return new CachingSessionFactory<FTPFile>(sf);
    }

    @Bean
    public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
        FtpInboundFileSynchronizer fileSynchronizer = new FtpInboundFileSynchronizer(ftpSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(false);
        fileSynchronizer.setRemoteDirectory("/");
        fileSynchronizer.setFilter(new FtpSimplePatternFileListFilter("*.xml"));
        return fileSynchronizer;
    }

    @Bean
    @InboundChannelAdapter(value="inputChannel", channel = "inputChannel")
    public MessageSource<File> ftpMessageSource() {
        FtpInboundFileSynchronizingMessageSource source = new FtpInboundFileSynchronizingMessageSource(
                ftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("ftp-inbound"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        return source;
    }

    @Bean
    @ServiceActivator(inputChannel = "inputChannel")
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                System.out.println(message.getPayload());
            }
        };
    }

    @Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata defaultPoller() {
        PollerMetadata pollerMetadata = new PollerMetadata();
        pollerMetadata.setTrigger(new PeriodicTrigger(10));
        return pollerMetadata;
    }

    @Bean
    @InboundChannelAdapter(value="outputChannel", channel = "outputChannel")
    public MessageSource<File> ftpMessageSource1() {
        FtpInboundFileSynchronizingMessageSource source = new FtpInboundFileSynchronizingMessageSource(
                ftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("ftp-outbound"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        return source;
    }

}

控制器代码如下图:

@RestController
public class FTPController {

    @Autowired
    MessageChannel outputChannel;

    @RequestMapping(value = "/ftpuploadtest", method = RequestMethod.GET)
    public void getM36Messages() {
        File file = new File("ftp.txt");
        Message<File> fileMessage = MessageBuilder.withPayload(file).build();
        outputChannel.send(fileMessage);
    }
}

当我运行应用程序时,我收到以下错误:

Description:
Field outputChannel in com.ftp.FTPController required a single bean, but 3 were found:
    - nullChannel: defined in null
    - errorChannel: defined in null
    - inputChannel: a programmatically registered singleton

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

请帮助解决这个问题。

【问题讨论】:

    标签: spring-boot ftp spring-integration message-channel


    【解决方案1】:

    首先,我认为您在outputChannel 组件方面犯了一些错误。

    如果是关于上传,那么你必须使用@ServiceActivatorFtpMessageHandler

    另一方面,对于此类问题,您必须为outputChannel 声明@Bean,并与@Autowired 一起,在FTPController 中添加@Qualifier("outputChannel")

    【讨论】:

    • 您也不应该在两个入站通道适配器中使用相同的同步器。
    • @Artem:如果我使用ServiceActivator注解,我需要提到一个inputChannel。在这里,我想手动将文件上传到输出通道。当输入通道发生变化时不应调用它。我应该做些什么?这就是我没有去 SeviceActivator 注解的原因。请原谅我,如果我听起来你很愚蠢。
    • 请解释一下任务。完全不清楚为什么您将消息通道视为上传内容。
    • @ArtemBilan:对不起,先生。更新了问题。
    • 再一次FtpInboundFileSynchronizingMessageSource 用于从 FTP 下载文件。您必须使用FtpMessageHandler 进行上传。是的,为此您可以发送带有文件负载的消息,@ServiceActivator 将为您完成这些工作。请阅读参考手册中有关 FTP 支持的更多信息
    【解决方案2】:

    使用 @Qualifier 和 @Autowired 。并保持变量名称与 bean 名称相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-31
      • 2013-11-12
      • 2017-12-18
      • 2016-09-27
      • 2013-01-29
      • 2019-01-10
      • 2018-12-27
      • 2021-04-02
      相关资源
      最近更新 更多