Spring Batch上下文持有者null

时间:2016-02-23 00:45:32

标签: java spring spring-batch

抱歉淹没了弹簧批次SO队列。

我从Job Scope模式开始,因为appears to not work in XML configuration for 3.0.6。我很可能只是感到困惑。

我尝试转到步骤范围,因为这似乎有效。这是我的bean的app-context.xml配置标头。这会启用scope="step"选项。

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:batch="http://www.springframework.org/schema/batch"
   xmlns:util="http://www.springframework.org/schema/util"
   xmlns:p="http://www.springframework.org/schema/p"
   xsi:schemaLocation="
    http://www.springframework.org/schema/batch
    http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/cache
    http://www.springframework.org/schema/cache/spring-cache.xsd">

但是,创建这些bean失败了。重要的是,这些是REST Easy客户端代理bean。我正如此定义:

<bean id="rootServiceBean" scope="step"
      class="com.myorg.ServiceProxyFactoryBean"
      p:baseUri="${rest.base.uri}"
      p:ticket="#{jobExecutionContext['jobSecrets']}" abstract="true"/>

然后在我的实例上:

<bean id="someServiceObject"
      parent="rootServiceBean"
      p:serviceInterface="com.myOrg.someServiceRest"/>

但是我从我的顶级工作,子工作,子步骤以及最终由...引起的步骤bean中得到错误。

由以下原因引起:org.springframework.beans.factory.BeanCreationException:创建名为'someService'的bean时出错:当前线程的作用域'step'无效;考虑为这个bean定义一个范围代理,如果你想从一个单例引用它;嵌套异常是java.lang.IllegalStateException:没有可用于步骤范围的上下文持有者     在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:341)     在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)     在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)     ......还有79个 引发者: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:327)     ... 81更多

我是否需要初始化工作?或者春季批次是否与易用客户端正在利用的代理冲突?

1 个答案:

答案 0 :(得分:1)

首先,由于一些假定的错误,你不应该放弃工作范围,更不用说“转移到步骤范围”;两者都很重要,有不同的用途。明显不同的是,作业范围的bean在作业持续时间内生存,并且在一个步骤的持续时间内使用步骤范围的bean。

如果确实存在错误,您可以像注册任何其他Spring上下文一样注册作业范围;实际上,更简单,因为Spring Batch的范围实现还负责注册自身并自动创建单例代理bean(如果将autoProxy属性设置为true,这是默认值) 。您只需要包含org.springframework.batch.core.scope.JobScope类型的bean。

至于您的错误,您没有提供足够的信息。可能有很多原因;我们所知道的是Spring尝试在没有任何作业步骤的情况下实例化一个步骤范围的bean,至少就试图获取bean的线程而言。所以你的第一步是确定触发bean实例化的内容。这可能是1)无法创建单例代理(如果您具有默认的自动代理设置,则不应该成为问题;请注意,在这种情况下,您指定的bean名称是给予单例代理的bean名称,实际步骤它委派的作用域bean被重命名为stepScopedTarget.<original bean name>),或者,更有可能的是,如果你有基础工作,2)过早地调用单例代理上的方法,即在步骤激活之前。如果您对同一作业使用多个线程,则可能还必须使用StepSynchronizationManager::register / JobSynchronizationManager::close将步骤范围传播给它。