You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Spring Integration中`java.lang.RuntimeException: No beanFactory`警告

问题根源及解决方案

问题原因

出现No beanFactory警告的核心原因是:你手动创建的SftpInboundFileSynchronizer和SftpInboundFileSynchronizingMessageSource没有被Spring容器托管,导致它们的父类AbstractExpressionEvaluator无法自动获取BeanFactory实例,而该实例是初始化表达式上下文的必要依赖。

同时,你在createFileSynchronizer方法中直接调用sessionFactory()(@Bean注解的方法),这会绕过Spring的Bean管理机制,每次调用都会创建新的CachingSessionFactory实例,既浪费资源,也进一步导致同步器无法关联到正确的容器上下文。

修复方案

将SftpInboundFileSynchronizer和MessageSource都声明为Spring Bean,通过依赖注入获取容器中的单例SessionFactory,让Spring负责管理它们的生命周期和依赖注入。

修改后的完整代码

@Configuration
public class SftpIntegrationConfig {

    @Bean
    public SessionFactory<SftpClient.DirEntry> sessionFactory() {
        return getDirEntrySessionFactory();
    }

    SessionFactory<SftpClient.DirEntry> getDirEntrySessionFactory() {
        DefaultSftpSessionFactory sessionFactory = new DefaultSftpSessionFactory();
        sessionFactory.setHost("localhost");
        sessionFactory.setPort(22);
        sessionFactory.setUser("test");
        sessionFactory.setPassword("test");
        sessionFactory.setAllowUnknownKeys(true);
        sessionFactory.isSharedSession();
        return new CachingSessionFactory<>(sessionFactory);
    }

    // 为每个远程目录创建独立的同步器Bean
    @Bean
    public SftpInboundFileSynchronizer fileSynchronizer987597720(SessionFactory<SftpClient.DirEntry> sessionFactory) {
        SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sessionFactory);
        fileSynchronizer.setDeleteRemoteFiles(true);
        fileSynchronizer.setRemoteDirectory("data/987597720");
        fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xml"));
        return fileSynchronizer;
    }

    @Bean
    public SftpInboundFileSynchronizer fileSynchronizer999999999(SessionFactory<SftpClient.DirEntry> sessionFactory) {
        SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sessionFactory);
        fileSynchronizer.setDeleteRemoteFiles(true);
        fileSynchronizer.setRemoteDirectory("data/999999999");
        fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xml"));
        return fileSynchronizer;
    }

    // 通过依赖注入获取同步器,创建MessageSource Bean
    @Bean
    public MessageSource<File> sftpMessageSource987597720(SftpInboundFileSynchronizer fileSynchronizer987597720) {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(fileSynchronizer987597720);
        source.setLocalDirectory(new File("C:\\Users\\jb\\src\\ihr-robot-integration\\target_folder"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        source.setMaxFetchSize(1);
        return source;
    }

    @Bean
    public MessageSource<File> sftpMessageSource999999999(SftpInboundFileSynchronizer fileSynchronizer999999999) {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(fileSynchronizer999999999);
        source.setLocalDirectory(new File("C:\\Users\\jb\\src\\ihr-robot-integration\\target_folder"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        source.setMaxFetchSize(1);
        return source;
    }

    @Bean
    public IntegrationFlow sftpFlow987597720() {
        return IntegrationFlow.from(sftpMessageSource987597720(),
                        c -> c.poller(Pollers.fixedDelay(10000)))
                .channel("sftpChannel")
                .get();
    }

    @Bean
    public IntegrationFlow sftpFlow999999999() {
        return IntegrationFlow.from(sftpMessageSource999999999(),
                        c -> c.poller(Pollers.fixedDelay(10000)))
                .channel("sftpChannel")
                .get();
    }

    @Bean
    public IntegrationFlow mergedSftpFlow(){
        return IntegrationFlow.from("sftpChannel")
                .channel("processChannel")
                .handle(message -> System.out.println(String.format("Processing new incoming file named: %s", message.getHeaders().get("file_name"))))
                .get();
    }

}

关键修改点

  1. 将SftpInboundFileSynchronizer拆分为两个独立的Bean,通过方法参数注入容器中的单例SessionFactory。
  2. MessageSource Bean同样通过依赖注入获取对应的同步器,确保所有组件都被Spring容器管理。
  3. 避免直接调用@Bean方法创建实例,改用依赖注入获取容器中的单例Bean,保证上下文一致性。

内容的提问来源于stack exchange,提问作者jcb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:38:11