我正在将Spring Batch集成到现有的Spring webapp中,并创建了三个简单的工作作为学习过程 . 然后我为作业/读者/编写者创建了一组祖先类,可以用来轻松地迁移旧的批处理作业 .

我们打算从Tomcat中异步运行作业作为单独的线程 . 我创建了一个用于管理和启动/停止它们的UI .

我有一个用@Configuration和@EnableBatchProcessing注释的类,它完成了为批处理模式设置所有全局类的工作;然后它还扫描基础包以获取特定祖先类的所有作业 . 然后它为相应的* Factory类的每个类名后缀,为该类执行getBean并使用它来注册每个作业:

Job job = jobFactory.createInstanceForRegistration();
jobRegistry.register(new ReferenceJobFactory(job));

createInstanceForRegistration方法使用applicationContext.getBean来获取作业/读/写类的实例,以将作业和步骤放在一起,最后:

((SimpleJob)job).setSteps(steps);
return job;

在UI中,列出了作业,我应该可以启动它们 . 但当我这样做时:

batchAuditId = jobOperator.start(jobName, parameters);

突然,一个NPE被抛出w / i AbstractJob / execute @ line 298:

jobParametersValidator.validate(execution.getJobParameters());

因为jobParametersValidator为null - 尽管它在类本身中使用默认值初始化:

private JobParametersValidator jobParametersValidator = 
    new DefaultJobParametersValidator();

更重要的是,作业类构造函数具有设置多个项的代码,包括验证器的覆盖:

super(BATCH_NAME, BATCH_TYPE_CODE, BATCH_FUNCTION, BATCH_PROCESS_AREA);
setLogger(LoggerFactory.getLogger(CustomJob.class));
getLogger().debug("constructed: {}", this.toString());

setParametersRequired(Boolean.TRUE); // this job requires parameters
setRestartable(Boolean.TRUE);
setJobParametersValidator(new CustomJobParametersValidatorImpl());

在部署期间,当Spring创建所有类时,我可以单步执行代码,并为该作业创建并设置覆盖验证器 .

然而,当jobOperator.start执行时,NPE被抛出 .

我没有理由这样做 . 它几乎就像jobOperator.start以不使用现有实例或我的自定义构造函数的方式以某种方式创建作业类的新实例 .

任何人都可以解释发生了什么?