gpt4 book ai didi

spring - 使用分区步骤在 Spring Batch 中访问 @JobScope bean

转载 作者:行者123 更新时间:2023-12-02 03:40:38 26 4
gpt4 key购买 nike

有没有办法访问分区步骤中定义为@JobScope的bean?

我们将 http 客户端 bean 定义为 @JobScope,因为它对于每个作业都是唯一的,但是动态创建的,并且我们需要它在从属步骤中发出发布请求。当我们 Autowiring 我们得到的一切时

Error creating bean with name 'scopedTarget.captureErpStockTasklet':
Scope 'step' is not active for the current thread; consider defining a
scoped proxy for this bean if you intend to refer to it from a singleton;
nested exception is java.lang.IllegalStateException: No context holder
available for step scope

这是作业配置类(我删除了不需要的所有内容,只留下分区步骤和 @JobScope 中的 Client 类的配置,因为在每个作业上都运行它需要针对具体工作:

@Configuration
@EnableBatchProcessing
@ComponentScan(basePackages = {"com.example.importjob"})
public class FrozenFileImportJobConfig {
@Value("${thread.pool:10}")
private int threadPoolSize;
@Value("${partitioner.max.thread.pool:10}")
private int maxThreadPoolSize;
@Value("${grid.size:10}")
private int gridSize;
@Value("${client.url:some_url}")
private int url;
@Value("${client.id:client_id}")
private int clientId;
@Value("${client.secret:secret}")
private int clientSecret;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private ErpStockIdPartitioner erpStockIdPartitioner;
@Autowired
private CaptureErpStockTasklet captureErpStockTasklet;
@Bean(destroyMethod = "destroy")
@JobScope
public Client client() {
return new Client(url, clientId, clientSecret);
}

public ExecutionContextPromotionListener contextPromotionListener() {
final ExecutionContextPromotionListener executionContextPromotionListener = new ExecutionContextPromotionListener();
executionContextPromotionListener.setKeys(new String[] {"erp_stock_ids"});
return executionContextPromotionListener;
}

public Step captureErpStockDBTaskletStep() {
return stepBuilderFactory.get("captureErpStockDBTaskletStep").tasklet(captureErpStockTasklet).build();
}

@Bean
public ThreadPoolTaskExecutor erpStockIdTaskExecutor() {
final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(threadPoolSize);
threadPoolTaskExecutor.setMaxPoolSize(maxThreadPoolSize);
threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
return threadPoolTaskExecutor;
}
public Step partitioningCaptureStep() {
return stepBuilderFactory.get("partitioningCaptureStep").partitioner(captureErpStockDBTaskletStep())
.partitioner("erpStockIdPartitioner", erpStockIdPartitioner).taskExecutor(erpStockIdTaskExecutor())
.gridSize(gridSize).allowStartIfComplete(true).build();
}
@Bean
public Job riverIslandFrozenFileImportJob() {
return jobBuilderFactory.get("riverIslandFrozenFileImportJob").start(partitioningCaptureStep()).build();
}
}

这里是captureErpStockDBTasklet,它作为分区步骤从主partitioningCaptureStep调用:

@Component
@StepScope
public class CaptureErpStockTasklet implements Tasklet {
private static final Logger LOG = LoggerFactory.getLogger(CaptureErpStockTasklet.class);
@Value("#{jobParameters[" + FtpJobParameters.ORGANIZATION_ID + "]}")
private Long organizationId;
@Autowired
private ErpStockRepository erpStockRepository;
@Autowired
private Client client;
@Override
public RepeatStatus execute(final StepContribution contribution, final ChunkContext chunkContext) throws Exception {
//importing of erp stock from DB, nothing special in that code so removed
client.captureErpStock(stock);
LOG.info("[{}] Finished importing ERP {}", organizationId, erpStock);
return RepeatStatus.FINISHED;
}
}

当我将配置 Clinet 更改为 @StepScope 时,它工作正常,但是我为每个步骤创建了客户端,这不是我想要的,我想要一份用于整个工作。

最佳答案

我认为这是在分区步骤中使用作业范围 bean 时 spring 批处理中的一个问题。

参见:https://jira.spring.io/browse/BATCH-2269Multi-threaded acces to Job Scope beans in Spring Batch 3.0

关于spring - 使用分区步骤在 Spring Batch 中访问 @JobScope bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56838132/

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