modular=true的java Spring批处理不适用于多个作业
我正在尝试使用@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.
但我认为这是模块化=真的全部要点。也就是说,处理名称冲突
另一方面,如果我启用bean覆盖,那么剩下的第二个作业将覆盖第一个作业
即@Autowired List<Job>
只有一个作业(从Dummy2.class
)
如何正确配置这些作业
# 1 楼答案
@EnableBatchProcessing
是一个Spring批处理注释,它早于Spring引导。因此,您需要考虑如何在Spring引导的上下文中工作。我看了一下你的申请表样本。让我先解释一下出了什么问题,然后再解释如何修复它问题
当您根据javadoc配置
@EnableBatchProcessing(modular=true)
时,在当前上下文中应该没有不希望引导的@Bean
定义。相反,您将ApplicationContextFactory
实现提供为@Bean
,每个实现都定义作业的子上下文然而,在您的应用程序中有一个陷阱。如前所述,
@EnableBatchProcessing
早于Spring Boot,因此您需要考虑它在Spring Boot的上下文中是如何工作的。在您的示例中,示例应用程序的所有类都在同一个包中。默认情况下,Spring Boot将对包中的@Configuration
注释类进行类路径扫描,您可以在包中定义一个用@SpringBootApplication
和“below”注释的类。因此,在您的示例应用程序中,Spring Boot会自动将Dummy1
和Dummy2
引入导致错误的父上下文中解决方案
要解决这个问题,您需要防止Spring引导在其类路径扫描中包含您的子上下文配置。为了证明这一点,我通过将
Dummy1
和Dummy2
移动到包com.example
(比用@SpringBootApplication
注释的类高一级)来测试您的示例应用程序。这阻止了Spring Boot通过类路径扫描来获取它们,并允许应用程序正确启动。。。还有两个小的调整:Dummy1
和Dummy2
中,您将两个作业名都配置为dummy-job-1
。将一个更改为dummy-job-2
,这解决了这个问题李>通过这些更改,您将能够构建应用程序并通过以下命令运行它:
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不拾取
Dummy1
和Dummy2
,应用程序就应该像您所期望的那样工作。祝你好运