Я пытаюсь запустить пакетное задание, в котором хочу сделать свой SQL-запрос динамическим. Но я получаю исключение при создании кода «Свойство или поле 'jobParameters' не может быть найдено в объекте типа 'org.springframework.beans.factory.config.BeanExpressionContext' - возможно, не общедоступный или недопустимый?». Ниже приведены фрагменты кода и трассировка исключения для него.
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?
Пожалуйста, укажите, почему параметры задания не распознаются и где происходит сбой в конфигурации.
Да. Но я пока получаю такое же исключение. Кажется, он вообще не распознает параметры задания.
Синтаксис, который я дал в моем предыдущем комментарии, правильный. Подробнее см. Здесь: docs.spring.io/spring-batch/4.0.x/reference/html/… Ваш bean-компонент снабжен аннотацией @StepScope. Это правильно. Я не вижу проблем с вашим кодом. Почему метод gameStoreSalesReader вашего компонента чтения элементов не является общедоступным? Вы пытались сделать это публичным, как и другие?
@SonamBhardwaj Вы нашли корень проблемы? или возможное решение? Я столкнулся с той же проблемой.




Объект Spring Batch StepScope - это объект, который уникален для определенного шага, а не для одного элемента. Как вы, наверное, знаете, область видимости bean-компонента в Spring по умолчанию - singleton. Но указание StepScope для компонента Spring Batch означает, что 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();
}
Вы пробовали добавлять простые кавычки вокруг имени параметра? Нравится:
@Value("#{jobParameters['maxDate']}")