使用SkipListener实现Ordered with scope =“step”:没有可用于步骤范围的上下文持有者

时间:2013-10-02 07:15:02

标签: listener spring-batch

当使用带有scope =“step”的skipListener实现Ordered时,我得到以下异常:

创建名为'scopedTarget.scopedTarget.fisalisBatchMeldungenListener'的bean时出错:当前线程的作用域'step'无效;考虑为这个bean定义一个范围代理,如果你想从一个单例引用它;嵌套异常是java.lang.IllegalStateException:没有可用于步骤范围的上下文持有者

如果我不让我的监听器实现Ordered异常不会发生。

这是我的Bean定义:

<bean id="erzeuger" class="...." scope="step">
    <property name="user" ref="user" />
    <property name="termin" ref="termin" />
    <property name="services" ref="services" 
</bean>

<bean id="listener" class="Listenerclass" scope="step">
    <property name="erzeuger" ref="erzeuger" />
</bean>

以下是我使用它的部分:

<step id="myStep" parent="abstractBatchStep" xmlns="http://www.springframework.org/schema/batch">
    <listeners merge="true">
    <listener ref="listener" />
    </listeners>
</step> 

有谁知道问题出在哪里?

1 个答案:

答案 0 :(得分:0)

我有一点:

当监听器添加到步骤时,步骤将检查其是否实现Ordered。如果是,则该步骤将侦听器添加到集合中,该集合将立即使用comperator进行排序。这个comperator调用getOrder(在侦听器的实例上为9。但是如果侦听器是stepScoped,SpringBatch Factory(下面的注释)必须返回&#34; real&#34; bean实例。但是此时& #34;真实的&#34; bean实例不存在。

对于sope =&#34;步骤&#34;读这个:

Scoped bean以不同的方式工作。创建上下文时,此bean将被包装到其他代理对象(默认情况下由CGLIB创建)中,该对象将传递给引用它的bean(此代理默认为singleton,例如shared)。因此,每次在运行时在代理上调用方法时,Spring都会与调用相交,请求工厂返回bean的实例并调用该bean上的方法。工厂轮流可以查找&#34;真实&#34; bean实例,例如在HTTP请求(&#34;请求&#34;范围)或HTTP会话(&#34;会话&#34;范围)和/或必要时创建新实例。延迟实例化允许使用&#34;运行时&#34;初始化作用域bean。 (范围)值,例如HTTP请求/会话中的值,在创建上下文时显然是未定义的。特别是&#34; step&#34; -scoped bean绑定到本地线程(请记住,并行运行步骤进行分区)。因此,当您对它们调用方法时,将取消引用作用域bean。最后,人们可以轻松打破这种优雅的春天意识形态&#34;通过在scoped bean上设置为另一个bean之后调用任何方法(例如在setter中):)