对于stepExecutionContext的Spring批量后期绑定不起作用

时间:2013-09-16 14:50:39

标签: spring lazy-initialization late-binding

我正在使用Spring批处理应用程序,并希望对stepExecutionContext使用后期绑定。我在解决我的错误方面遇到了问题。

以下是我的读者,它具有使用后期绑定的sql属性:

<bean id="itemReader_S4_JPolicy" class="com.aegonusa.etl.readers.JDBCItemReader" scope="step">
    <property name="jobParameters" ref="jobParameters" />
    <property name="dataSource" ref="readDataSource" />
    <property name="rowMapper">
    <bean class="com.aegonusa.etl.readers.ResultSetRowMapper" scope="step" />
    </property>
    <property name="sql"
        value="#{stepExecutionContext['readQuery']}"></property>
</bean>

我在下面的类中设置了这个属性('readQuery'):

public class StepListener实现了StepExecutionListener {

.... ....

@Override
public void beforeStep(StepExecution execution) {
            String s = "select getdate();
    StepSynchronizationManager.getContext().setAttribute("readQuery", s);

.....         } ..... }

请注意,我可以使用jobParameters进行后期绑定。 但是使用stepExecutionContext,我得到了以下的exc。我在论坛上尝试了很多帖子,但我无法解决它:

Throwable occurred: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lazyBindingProxy.itemReader_S4_JPolicy#sysinit' defined in class path resource [Load_InforceToStage.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot bind to placeholder: stepExecutionContext['readQuery']
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(AccessController.java:224)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:302)
at org.springframework.batch.core.scope.StepScope.get(StepScope.java:150)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getTarget(PlaceholderTargetSource.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
at $Proxy1.close(Unknown Source)
at org.springframework.batch.item.support.CompositeItemStream.close(CompositeItemStream.java:83)
at org.springframework.batch.core.step.item.ChunkMonitor.close(ChunkMonitor.java:99)
at org.springframework.batch.item.support.CompositeItemStream.close(CompositeItemStream.java:83)
at org.springframework.batch.core.step.tasklet.TaskletStep.close(TaskletStep.java:297)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:255)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:349)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:574)
at com.ebsadm.lh.LHSHEDToStage.runJob(LHSHEDToStage.java:124)
at com.ebsadm.lh.LHSHEDToStage.main(LHSHEDToStage.java:111)
at com.ebdadm.lh.TestLHSHEDToStage.testInforceLoadToStage(TestLHSHEDToStage.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

引起:java.lang.IllegalStateException:无法绑定到占位符:stepExecutionContext ['readQuery']     在org.springframework.batch.core.scope.util.PlaceholderTargetSource $ 1.convertIfNecessary(PlaceholderTargetSource.java:140)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1294)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)     在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)     ......还有50个

请帮助。

2 个答案:

答案 0 :(得分:1)

我希望getExecutionContext上的StepExecution来电给您正确的背景信息。

@Override
public void beforeStep(StepExecution execution) {
    String s = "select getdate()";
    execution.getExecutionContext().putString("readQuery", s);  
} 

您当前的解决方案是StepContextStepContext是公开并用于表达式解析的对象,而与ExecutionContext关联的StepExecution是实际的stepExecutionContext。 ItemReadersItemWriters这样的对象也使用ExecutionContext来更新状态(跳过的项目,提交计数等)。

答案 1 :(得分:0)

尝试以下任何一项:

  1. 使用promotionListener bean来提升步骤之间变量的范围。
  2. 使用bean而不是executionContext。