java - 带有 modular=true 的 Spring Batch 不适用于多个作业

标签 java spring spring-batch

我正在尝试使用 @EnableBatchProcessing(modular = true) 配置两个作业.据我所知,这是为了防止命名冲突。

这是我的工作配置:

@Configuration
public class Dummy1 {

    @Autowired
    JobBuilderFactory jobBuilderFactory;
    @Autowired
    StepBuilderFactory stepBuilderFactory;

    @Bean
    public Step step() {
        // < build step. Omitted for code clarity > 
    }

    @Bean
    public Job getJob() {
        return jobBuilderFactory.get("dummy-job-1")
                .start(step())
                .build();
    }
}

我有一个类似的类,名为 Dummy2 .

我还定义了以下配置:

@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing(modular = true)
public class BatchConfig {

    @Bean
    public ApplicationContextFactory getDummy1() {
        return new GenericApplicationContextFactory(Dummy1.class);
    }

    @Bean
    public ApplicationContextFactory getDummy2() {
        return new GenericApplicationContextFactory(Dummy2.class);
    }
}

运行应用程序时我得到:

The bean 'step', defined in class path resource [~PATH~/Dumm2.class], could not be registered. A bean with that name has already been defined in class path resource [~PATH~/Dumm1.class] and overriding is disabled.

但我认为这就是 modular=true 的全部意义。也就是说,处理名称冲突。

另一方面,如果我启用 bean 覆盖,我将剩下第二个作业覆盖第一个作业。

@Autowired List<Job>只有一份工作(来自 Dummy2.class )

如何正确配置这些作业?

最佳答案

@EnableBatchProcessing是早于 Spring Boot 的 Spring Batch 注解。因此,您需要考虑它在 Spring Boot 上下文中的工作方式。我查看了您的示例应用程序。让我先解释一下出了什么问题,然后再解释如何修复它。

问题

当你配置 @EnableBatchProcessing(modular=true) ,根据 javadoc,你应该没有 @Bean当前上下文中您不想被引导的定义。相反,您提供 ApplicationContextFactory实现为 @Bean ,其中每一个都定义了作业的子上下文。

但是,在您的应用程序中有一个问题。如前所述,@EnableBatchProcessing早于 Spring Boot,因此您需要考虑它如何在 Spring Boot 的上下文中工作。在您的例子中,示例应用程序将所有类都放在同一个包中。默认情况下,Spring Boot 将对 @Configuration 进行类路径扫描。包中带注释的类,您定义的类用 @SpringBootApplication 注释和“下方”。因此,在您的示例应用程序中,Spring Boot 引入了 Dummy1。和 Dummy2自动进入导致错误的父上下文。

解决方案

要解决此问题,您需要防止 Spring Boot 在其类路径扫描中包含您的子上下文配置。为了证明这一点,我通过移动 Dummy1 测试了您的示例应用程序和 Dummy2到包裹com.example (一级 @SpringBootApplication 注释的类)。这阻止了 Spring Boot 通过其类路径扫描来拾取它们并允许应用程序正确启动......通过另外两个小调整:

  1. 虽然 bean 名称可以在模块化配置中重复,但实际的作业名称不能。在 Dummy1Dummy2 ,您将两个作业名称都配置为 dummy-job-1 .把一个改成dummy-job-2这解决了这个问题。
  2. Spring Boot 需要用于批处理应用程序的数据源。我将 HSQLDB 添加到 POM 以证明我的修复成功了。

通过这些更改,您将能够构建您的应用程序并通过以下命令运行它:java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.batch.job.names=dummy-job-1运行作业 1 或 java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.batch.job.names=dummy-job-2运行作业 2。

还有许多其他方法可以移动类以防止 Spring Boot 的类路径扫描来拾取它们,只要 Spring Boot 不拾取 Dummy1Dummy2 ,该应用程序应按预期运行。祝你好运!

关于java - 带有 modular=true 的 Spring Batch 不适用于多个作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61370476/

相关文章:

带有持久存储作业注册表的 spring batch 重新启 Action 业

java - 当按下 MainActivity 中的按钮时实现 onReceive()

java - 由于自签名或过时版本的安全异常,JDK 7u45 应用程序被阻止

Java:JButtons 无法与操作监听器一起使用

java - 微服务未从 : http://localhost:8888 Springboot 处的服务器获取配置

java - 当我运行作业时,springBatch 中的 ItemReadListener 未运行

java - 如何将 "translate"此扫描仪输入到 JOptionPane showOptionDialog

Java SpEL EL1043E : Unexpected token. 预期为 'rparen())' 但实际为 'comma(,)'

Spring框架库

java - 如何在作业中输入参数