【问题标题】:Spring with Apache Beam使用 Apache Beam 的 Spring
【发布时间】:2019-10-04 19:53:51
【问题描述】:

我想将 Spring 与将在 Google Cloud Data flow Runner 上运行的 Apache Beam 结合使用。数据流作业应该能够在执行流水线步骤时使用 Spring Runtime 应用程序上下文。我想在我的 Apache Beam 管道中使用 Spring 功能来处理 DI 和其他东西。在谷歌上浏览了几个小时后,我找不到任何显示 Apache Beam 中的 Spring 集成的帖子或文档。所以,如果有人用 Apache Beam 尝试过 spring,请告诉我。

在主类中,我已经初始化了 spring 应用程序上下文,但在执行管道步骤时它不可用。我得到自动装配 bean 的空指针异常。我想问题是,在运行时上下文对工作线程不可用。

 public static void main(String[] args) {
    initSpringApplicationContext();

    GcmOptions options = PipelineOptionsFactory.fromArgs(args)
        .withValidation()
        .as(GcmOptions.class);
    Pipeline pipeline = Pipeline.create(options);
    // pipeline definition
}

我想将 spring 应用程序上下文注入到每个 ParDo 函数中。

【问题讨论】:

    标签: spring google-cloud-dataflow apache-beam


    【解决方案1】:

    这里的问题是 ApplicationContext 在任何工作人员上都不可用,因为 main 方法仅在构造作业时被调用,而不是在任何工作人员机器上。因此,initSpringApplicationContext 永远不会被任何工作人员调用。

    我从未尝试在 Apache Beam 中使用 Spring,但我想将 initSpringApplicationContext 移动到静态初始化程序块中会导致您预期的结果。

    public class ApplicationContextHolder {
    
        private static final ApplicationContext CTX;
    
        static {
            CTX = initApplicationContext();
        }
    
        public static ApplicationContext getContext() {
            return CTX;
        }
    }
    

    请注意,仅此一点不应被视为在 Apache Beam 中使用 Spring 的最佳实践,因为它不能很好地集成到 Apache Beam 的生命周期中。例如,在应用程序上下文的初始化过程中发生错误时,它会出现在使用ApplicationContextHolder 的第一个位置。因此,我建议从静态初始化程序块中提取initApplicationContext,并针对 Apache Beam 的生命周期显式调用它。 setup 阶段将是一个很好的地方。

    【讨论】:

    • 我使用 setup 来初始化创建 new AnnotationConfigApplicationContext( AppConfig.class); 的应用程序上下文,但是我在扫描我的组件时遇到了问题。我的 appConfig 类
    • 当您提供更多信息时,我们可能会为您提供帮助。您是否还检查了所有必需的组件是否在 worker 上可用,即在它的类路径上?
    • 我用@Component 注释注释了几个类,并且我在我的appConfig 中定义了几个bean。其中只有在我的 appConfig 中定义的 bean 是可以访问的,而不是带注释的 bean。这是我的 appConfig 结构。创建新的 AnnotationConfigApplicationContext 对象时似乎没有触发组件扫描。你有什么问题。 @Configuration @PropertySource("classpath:app.properties") @ComponentScan(basePackages="com.abc") public class AppConfig { // Bean definitions with @Bean annotation. }
    • 据我所知,AnnotationConfigApplicationContext 不排除组件扫描等。它在本地有效吗?例如,当您在 main 方法中构造 ApplicationContext 时。如果它在这种情况下也不起作用,则问题出在您的 Spring 配置上,与 Apache Beam 无关。
    • 是的,它在本地工作。我编写了 test main 方法来测试它,它工作得很好。我可以看到用 @Component 注释打印的 bean。 ' public class SpringTestMain { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext( AppConfig.class); System.out.println(applicationContext.containsBean("googleRecordParser")); for (String beanName : applicationContext.getBeanDefinitionNames()) { System.out.println(beanName); } } } '
    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2020-01-17
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多