我目前正在使用Spring Batch来运行处理文件的作业,在每一行上执行一些操作并将输出写入另一个文件。
这是在'核心'产品中开发的,但现在(一如既往)我们有一些客户特定的要求,要求在工作中包含一些额外的步骤。
我已经能够进行概念验证,使用常见的Spring功能,可以通过使用工作的不同名称(如果我们定义)通过额外步骤“替换”另一个工作它们在同一个Configuration类中)或者通过创建一个完全不同的Configuration类并将其作为Spring上下文加载。
我要问的是,我几乎'在那里,如果可以轻松定义基本作业(可能是否有初始步骤),然后只添加对该特定有意义的步骤'客户端”。
我正在使用标准类继承来执行此操作,但它无法与标准Spring工具一起正常工作,因为Spring不知道要使用哪个“getSteps”方法的实现(下面的代码)。
abstract class JobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
protected StepBuilderFactory stepBuilderFactory;
@Bean
Job job() {
List<Step> steps = getSteps();
final JobBuilder jobBuilder = jobBuilderFactory.get("job")
.incrementer(new RunIdIncrementer());
SimpleJobBuilder builder = jobBuilder.start(steps.remove(0));
for (Step s : steps) {
builder = builder.next(s);
}
return builder.build();
}
protected abstract List<Step> getSteps();
}
@Configuration
@Import(BaseConfig.class)
public class Client1JobConfig extends JobConfig {
@Override
protected List<Step> getSteps() {
List<Step> steps = new ArrayList<>();
steps.add(step1());
return steps;
}
Step step1() {
return stepBuilderFactory.get("step1")
.<Integer, Integer>chunk(1)
.reader(dummyReader())
.processor(processor1())
.writer(dummyWriter())
.build();
}
}
@Configuration
@Import(BaseConfig.class)
public class Client2JobConfig extends JobConfig {
@Override
protected List<Step> getSteps() {
List<Step> steps = new ArrayList<>();
steps.add(step1());
steps.add(step2());
return steps;
}
Step step1() {
return stepBuilderFactory.get("step1")
.<Integer, Integer>chunk(1)
.reader(dummyReader())
.processor(processor1())
.writer(dummyWriter())
.build();
}
Step step2() {
return stepBuilderFactory.get("step2")
.<Integer, Integer>chunk(1)
.reader(dummyReader())
.processor(processor2())
.writer(dummyWriter())
.build();
}
}
如果我只将一个Configuration类加载到Spring上下文中但是如果我加载了所有的Configuration类(通过组件扫描,或者手动将它们添加到上下文中),我可以使它工作当然它不起作用,因为没有办法选择对方的一个实现。
我还可以通过使用不同名称的作业(如“client1”和“client2”)来使其工作,但是假设我无法更改调用代码并且作业是自动装配的。我怎么能有一些'相同'但步骤不同?
有没有更好的方法来实现这一目标?