gpt4 book ai didi

spring - 如何从休息服务开始批处理。 afterJob 运行但 EnableBatchProcessing 仅在部署后运行

转载 作者:行者123 更新时间:2023-12-05 08:57:29 24 4
gpt4 key购买 nike

我遵循了教程 https://spring.io/guides/gs/batch-processing/一旦应用程序启动,它基本上读取电子表格并将数据插入数据库。我想在每次调用rest服务时执行读取过程,所以我在这个应用程序中添加了一个 Controller 。为了调用工作,我遵循了 How to trigger a job using a rest web service? 中的建议现在它出现了我的问题:每当我调用 rest 服务时,它只运行 afterJob 方法。我读了how to select which spring batch job to run based on application argument - spring boot java config (这与我的问题有一定的相似性)和其中指出的优秀博客文章,但我仍然被困住了。我想在其余服务之后调用“public ItemReader reader()”,我希望遵循与通过 main() 启动应用程序时相同的流程。我的意思是,和springboot部署时一样的流程。我想我的困惑在于 @EnableBatchProcessing 或 JobExecutionListenerSupport 但我真的坚持下去。以下是最重要的片段。

Controller

@Autowired
JobLauncher jobLauncher;

@Autowired
Job job;

@RequestMapping("/runit")
public void handle() throws Exception{
JobParameters jobParameters =
new JobParametersBuilder()
.addLong("time",System.currentTimeMillis()).toJobParameters();
jobLauncher.run(job, jobParameters);
}

监听器

@Component
public class JobCompletionNotificationListener extends
JobExecutionListenerSupport {

@Override
public void afterJob(JobExecution jobExecution) {
if(jobExecution.getStatus() == BatchStatus.COMPLETED) {

批量配置

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
// tag::readerwriterprocessor[]
@Bean
public ItemReader<Person> reader() {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "firstName", "lastName" });
}});

setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});

return reader;
}

@Bean
public ItemProcessor<Person, Person> processor() {
return new PersonItemProcessor();
}

@Bean
public ItemWriter<Person> writer(DataSource dataSource) {
JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());

writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");

writer.setDataSource(dataSource);
return writer;
}

@Bean
public Job importUserJob(JobBuilderFactory jobs, Step s1, JobExecutionListener listener) {
return jobs.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(s1)
.end()
.build();
}

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<Person> reader,
ItemWriter<Person> writer, ItemProcessor<Person, Person> processor) {
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}

application.properties

application.properties
# SPRING BATCH (BatchDatabaseInitializer)
spring.batch.job.enabled=false
spring.batch.initializer.enabled=false

最佳答案

在深入讨论这个问题之后,真正的“问题”是 ItemReader 被创建一次,而不是每次 REST 调用一次(也就是每次执行作业一次)。要解决此问题,请将 ItemReader 步骤限定范围。这将允许您在每次运行时获得一个新的阅读器实例,这也使您能够根据作业参数注入(inject)文件名。

从代码的角度,改变这个:

@Bean
public ItemReader<Person> reader() {

为此:

@Bean
@StepScope
public FlatFileItemReader<Person> reader() {

返回类型改变的原因是Spring Batch会自动为你注册ItemStream。但是,当使用 @StepScope 时,我们只会看到您定义的返回值。在这种情况下,ItemReader 不会扩展/实现 ItemStream,因此我们不知道您正在返回我们应该自动注册的内容。通过返回 FlatFileItemReader,我们可以看到所有接口(interface)/等等,并且可以为您应用“魔法”。

关于spring - 如何从休息服务开始批处理。 afterJob 运行但 EnableBatchProcessing 仅在部署后运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31329421/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com