我正在尝试运行批处理作业,在此我想使我的SQL查询动态化。但是,我在构建代码为时遇到了一个异常:“在类型为'org.springframework.beans.factory.config.BeanExpressionContext'的对象上找不到属性或字段'jobParameters'-可能不是公共的或无效的?” 。下面是相同的代码段和异常跟踪。
BatchConfig
@Configuration
@EnableBatchProcessing
public class StoreSalesBatchConfiguration {
@Autowired
@Qualifier("jobBuilderFactory")
private JobBuilderFactory jobBuilderFactory;
@Autowired
@Qualifier("stepBuilderFactory")
private StepBuilderFactory stepBuilderFactory;
@Autowired
@Qualifier("jobCompletionNotificationListener")
private JobCompletionNotificationListener jobCompletionNotificationListener;
@Autowired
@Qualifier("jobLauncher")
private JobLauncher jobLauncher;
@Autowired
@Qualifier("storeSalesJob")
private Job storeSalesJob;
@Autowired
private GameStoreSalesRepository storeSalesRepository;
@Bean
@StepScope
ItemReader<GameStoreSales> gameStoreSalesReader(@Qualifier("gdwMpsBatch") final DataSource dataSource,
@Value("#{jobParameters[maxDate]}") String maxDate) {
JdbcCursorItemReader<GameStoreSales> databaseReader = new JdbcCursorItemReader<>();
databaseReader.setDataSource(dataSource);
databaseReader.setSql(CommonConstants.STORE_SALES_QUERY);
databaseReader.setPreparedStatementSetter(new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(1, maxDate);
}
});
databaseReader.setRowMapper(new BeanPropertyRowMapper<>(GameStoreSales.class));
return databaseReader;
}
@Bean
public GameStoreSalesProcessor gameStoreSalesProcessor() {
return new GameStoreSalesProcessor();
}
@Bean
public ItemWriter<GameStoreSales> gameStoreSalesWriter() throws Exception {
return new GameStoreSalesWriter();
}
@Bean
public Step gameStoreSalesStep(@Qualifier("gdwMpsBatch") final DataSource dataSource,
@Value("#{jobParameters[maxDate]}") String maxDate) throws Exception {
return stepBuilderFactory.get("gameStoreSalesStep").<GameStoreSales, GameStoreSales>chunk(1000)
.reader(gameStoreSalesReader(dataSource,maxDate)).processor(gameStoreSalesProcessor()).writer(gameStoreSalesWriter()).build();
}
@Bean(name = "storeSalesJob")
public Job storeSalesJob(Step gameStoreSalesStep) {
return jobBuilderFactory.get("storeSalesJob").incrementer(new RunIdIncrementer())
.listener(jobCompletionNotificationListener).flow(gameStoreSalesStep).end().build();
}
@Scheduled(cron = "*/30 * * * * *")
public void runStoreSalesJob() throws JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException, JobParametersInvalidException {
String dateParam = new Date().toString();
String maxDate = storeSalesRepository.getMaxCalDate();
JobParameters param = new JobParametersBuilder().addString("date", dateParam)
.addString("maxDate", weekEnd)
.toJobParameters();
try{
jobLauncher.run(storeSalesJob, param);
} catch(Exception e){
e.printStackTrace();
}
}
}
异常跟踪:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'storeSalesBatchConfiguration': Unsatisfied dependency expressed through field 'storeSalesJob'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'storeSalesJob' defined in class path resource [com/staples/mpsbatch/config/StoreSalesBatchConfiguration.class]: Unsatisfied dependency expressed through method 'storeSalesJob' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gameStoreSalesStep' defined in class path resource [com/staples/mpsbatch/config/StoreSalesBatchConfiguration.class]: Unsatisfied dependency expressed through method 'gameStoreSalesStep' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'storeSalesJob' defined in class path resource [com/staples/mpsbatch/config/StoreSalesBatchConfiguration.class]: Unsatisfied dependency expressed through method 'storeSalesJob' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gameStoreSalesStep' defined in class path resource [com/staples/mpsbatch/config/StoreSalesBatchConfiguration.class]: Unsatisfied dependency expressed through method 'gameStoreSalesStep' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'gameStoreSalesStep' defined in class path resource [com/staples/mpsbatch/config/StoreSalesBatchConfiguration.class]: Unsatisfied dependency expressed through method 'gameStoreSalesStep' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
请提出为什么无法识别jobParameters以及配置错误的地方。
答案 0 :(得分:0)
Spring Batch StepScope 对象是特定步骤所独有的对象,而不是单个对象。您可能知道,Spring 中的默认 bean 作用域是单例。但是通过将 Spring Batch 组件指定为 StepScope 意味着 Spring Batch 将使用 spring 容器为每个步骤执行实例化该组件的新实例。
这对于进行参数后期绑定通常很有用,其中参数可以在 StepContext 或 JobExecutionContext 级别指定,并且需要替换为占位符,就像您的具有文件名要求的示例一样。
使用 StepScope 的另一个有用的原因是当您决定在并行步骤中重用相同的组件时。如果组件管理任何内部状态,重要的是它是基于 StepScope 的,这样一个线程不会损害另一个线程管理的状态(例如,给定步骤的每个线程都有自己的 StepScope 组件实例)。
尝试使用 StepScope 进行注释:
@Bean
@StepScope
public Step gameStoreSalesStep(@Qualifier("gdwMpsBatch") final DataSource dataSource,
@Value("#{jobParameters[maxDate]}") String maxDate) throws Exception {
return stepBuilderFactory.get("gameStoreSalesStep").<GameStoreSales, GameStoreSales>chunk(1000)
.reader(gameStoreSalesReader(dataSource,maxDate)).processor(gameStoreSalesProcessor()).writer(gameStoreSalesWriter()).build();
}