如何使用单个阅读器配置Spring批处理作业并根据返回的对象调用多个编写器

时间:2015-10-25 13:22:38

标签: spring-batch

下面是我正在使用的作业文件。

<batch:job id="job1">
    <batch:step id="step1">
        <batch:tasklet>
            <batch:chunk reader="reader" processor="processor" writer="ItemWriter" commit-interval="3">
            </batch:chunk>
        </batch:tasklet>
    </batch:step>
</batch:job>

2 个答案:

答案 0 :(得分:1)

正如Luca的评论中所述,您可以使用需要ClassifierCompositeItemWriter的{​​{1}}。

后者的少数几个实现之一是org.springframework.classify.Classifier,它依次为org.springframework.classify.BackToBackPatternClassifierrouterDelegate

matcherMap是一个bean,其注释方法为routerDelegate。此方法将使用@Classifier并返回Object。然后,此字符串将与您在String中声明的值进行匹配,并相应地调用module-context

以下是一个例子:

ItemWriter

这就是分类器的样子(这是一个使用Reflect API来调用作为对象传递的方法的通用分类器):

<bean class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
    <property name="classifier">
        <bean class="org.springframework.classify.BackToBackPatternClassifier">
            <property name="routerDelegate">
                <bean class="xx.xx.xx.YourClassifier"></bean>
            </property>
            <property name="matcherMap">
                <map>
                    <entry key="value1">
                        <bean class="xx.xx.xx.YourItemWriter1></bean>
                    </entry>
                    <entry key="value2">
                        <bean class="xx.xx.xx.YourItemWriter2></bean>
                    </entry>
                </map>
            </property>
        </bean>
    </property>
</bean>

此分类器以这种方式使用,其中public class GenericClassifier<T> { private String methodName; @Classifier public String classify(T classifiable) { Method method; String value = ""; try { // Get the method with Reflect method = classifiable.getClass().getMethod(methodName); // Call the method with Reflect value= (String) method.invoke(classifiable); } catch (Exception e) { // Error management } return value; } public void setMethodName(String methodName) { this.methodName = methodName; } } 是要分类的Object类的公共方法(不带括号):

YourMethod

然后<bean class="xx.xx.xx.GenericClassifier"> <property name="methodName" value="YourMethod"></property> </bean> 返回的value字符串与Classifier的{​​{1}}的{​​{1}}匹配。

答案 1 :(得分:0)

忘记添加我找到的解决方案。 以下解决方案适合我。编写了代码并且工作正常。

首先,您需要一个分类器。实现Classifier接口或使用@Classifier注释classify()方法。

这里我使用了注释。

public class MyClassifier 
{ 
  @Classifier public String classify(Policy pol)
  { 
    return pol.getPolCode;// returns "01", "02" 
  } 
}

添加分类器bean

<bean id="myClassifier" class="org.springframework.batch.classify.BackToBackPatternClassifier">
   <property name="routerDelegate"> 
     <bean class="MyClassifier" /> 
   </property> 
   <property name="matcherMap"> 
     <map> 
       <entry key="01" value-ref="pol01ItemWriter" /> 
       <entry key="02" value-ref="pol02ItemWriter" />
     </map>
   </property>
</bean>

添加您的编写器bean,如下所示

<bean id="ItemWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
   <property name="myClassifier" ref="myClassifier" /> 
</bean>

上面的代码可能会抛出WriterNotOpenException。为此,您需要将batch:stream添加到步骤。

<batch:step id="step1">
  <batch:tasklet> 
    <batch:chunk reader="reader" processor="processor" writer="ItemWriter" commit-interval="3">
      <batch:streams> 
        <batch:stream ref="pol01ItemWriter"/>
        <batch:stream ref="pol02ItemWriter"/>
      </batch:streams>
    </batch:chunk>
  </batch:tasklet>
</batch:step>