在创建弹簧批处理bean时获取“范围'步骤'对于当前线程不活动”

Posted

技术标签:

【中文标题】在创建弹簧批处理bean时获取“范围\'步骤\'对于当前线程不活动”【英文标题】:Getting "Scope 'step' is not active for the current thread" while creating spring batch beans在创建弹簧批处理bean时获取“范围'步骤'对于当前线程不活动” 【发布时间】:2018-11-05 07:31:53 【问题描述】:

在我的 Spring 批处理配置中,我正在尝试设置一个分区步骤,该步骤从 JobParameters 访问值,如下所示:

@Bean
@Qualifier("partitionJob")
public Job partitionJob() throws Exception 

    return jobBuilderFactory
            .get("partitionJob")
            .incrementer(new RunIdIncrementer())
            .start(partitionStep(null))
            .build();


@Bean
@StepScope //I'm getting exception here - > Error creating bean 
public Step partitionStep(
        @Value("#jobParameters[gridSize]") String gridSize)
        throws Exception 

    return stepBuilderFactory
            .get("partitionStep")
            .partitioner("slaveStep", partitioner())
            .gridSize(
                    StringUtils.isEmpty(gridSize) ? 10 : Integer
                            .parseInt(gridSize))
            .step(slaveStep(50000))
            .taskExecutor(threadPoolTaskExecutor()).build();


@Bean
@StepScope
public Step slaveStep(int chunkSize) throws Exception 

    return stepBuilderFactory
            .get("slaveStep")
            .<Person,Person> chunk(chunkSize)
            .reader(jdbcPagingItemReader()),
            .writer(csvFileWriterParts())
            .listener(stepExecutionListener()).build();

我在我的 SpringBoot 应用程序中添加了@EnableBatchProcessing 注解。

因为我想在构建步骤时访问 JobParameters,所以我使用了@StepScope。我有一个工作正常的示例,没有 @StepScope 注释,但在这种情况下,我没有从上下文访问任何 JobParameters 或任何内容。

但是如果我在 partitionStep 上使用 StepScope 注释,我会得到 ​​p>

创建名为“scopedTarget.partitionStep”的 bean 时出错:范围 'step' 对当前线程无效;考虑定义一个 如果您打算从 单身人士;嵌套异常是 java.lang.IllegalStateException: No 可用于步骤范围的上下文持有者

但如果我将其更改为 JobScope,那么它会在 slaveStep() 处失败并显示相同的错误消息。

在这种情况下使用的正确范围是什么?如何解决我遇到的这个问题?

在配置 spring bean 时访问 JobParameters 的更好方法是什么?

异常堆栈如下

2018-05-25 21:07:32,075 错误 [主要] org.springframework.batch.core.job.AbstractJob :遇到致命的 错误执行作业 org.springframework.beans.factory.BeanCreationException:错误 创建名为“scopedTarget.partitionStep”的bean:范围“step”是 对当前线程无效;考虑定义一个作用域代理 如果您打算从单例中引用此 bean;嵌套的 例外是 java.lang.IllegalStateException: No context holder 可用于步骤范围 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:361) 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 在 org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) 在 com.sun.proxy.$Proxy55.getName(Unknown Source) 在 org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:115) 在 org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:392) 在 org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135) 在 org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) 在 org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) 在 org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) 在 org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在 org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 在 com.sun.proxy.$Proxy54.run(未知来源) com.sample.main(ExtractApplication.java:58) 引起:java.lang.IllegalStateException:没有上下文持有者 可用于步骤范围 org.springframework.batch.core.scope.StepScope.getContext(StepScope.java:167) 在 org.springframework.batch.core.scope.StepScope.get(StepScope.java:99) 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:346) ...省略了23个常用框架

如果我修改为 JobScope,我会在 slaveStep 上得到异常,这类似于上面的异常。

【问题讨论】:

这个类中不太可能抛出异常。显示完整的堆栈跟踪老兄 我已经用异常堆栈更新了我的原始帖子。 这可能会帮助你Scope step issue 感谢您提供的链接。我会试试这个选项 我在相同的用例中遇到了同样的问题,你能分享一下对你有用的解决方案吗? 【参考方案1】:

请尝试由 Manh 发布的 Spring batch scope issue while using spring boot 选项。我想它解决了这个问题。不幸的是,我无法再访问代码库,以确认我为修复所做的工作。

【讨论】:

我遇到了同样的问题,您在上面分享的链接已经解决了这个问题。我使用的 spring-batch 版本是 3.0.7.RELEASE。谢谢:)

以上是关于在创建弹簧批处理bean时获取“范围'步骤'对于当前线程不活动”的主要内容,如果未能解决你的问题,请参考以下文章

使用休眠和弹簧更新

创建名为“activityController”的 bean 时出错

动态类型种姓弹簧路径变量

从弹簧工具套件连接到数据库时出错

将jpa实体作为弹簧组件是一个好主意

弹簧默认范围单例与否?