当前位置: 首页 > 知识库问答 >
问题:

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

燕雨石
2023-03-14

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

<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个答案

和和裕
2023-03-14

忘记添加我找到的解决方案。下面的解决方案对我很有用。编译了代码,效果很好。

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

这里我使用了注释。

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 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>
焦驰
2023-03-14

正如Luca的评论中所说,您可以使用ClassifierCompositeItemWriter,它需要org.springframework.classify.Classifier

后者为数不多的实现之一是org.springframework.classify.BackToBackPatternClassifier,它又需要一个路由器Delegate和一个匹配器Map

routerServer ate是一个bean,它将具有一个用@分类器注释的方法。此方法将获取一个Object并返回一个String。然后,此字符串将与您在模块上下文中声明的值匹配,并相应地调用ItemWriter

这里有一个例子:

<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>

下面是一个分类器的样子(这是一个通用分类器,使用Reflect API调用一个方法作为对象的参数传递) :

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;
    }
}

此分类器的用法如下,其中< code>YourMethod是要分类的对象的类的公共方法(不带括号) :

<bean class="xx.xx.xx.GenericClassifier">
    <property name="methodName" value="YourMethod"></property>
</bean>

然后将分类器返回的valueString与matcherMap条目key匹配。

 类似资料:
  • 不管模式如何,一个基于JobParameters的同步使用不同读取器的解决方案将会很有帮助。

  • CompositeItemWriter:当我需要将项目平均地分给Writer时,似乎会将所有读取的项目传递给所有的Writer。 BacktoBackPatternClassifier:我并不真正需要分类器,因为我是均匀地拆分项目。 有没有另一种方式,让一个读者和多个作者? 或者我可以在Writer中手动创建线程?

  • 我刚开始使用Spring批处理,我有一个特殊问题。我希望使用从3个不同的jpa查询中获取结果,并分别处理它们,然后使用将它们写入一个统一的XML文件。 对于eg,生成的XML看起来像是,

  • 问题是:如何使spring批处理中的条目读取器传递列表而不是单个对象。 我已经搜索过了,一些答案是修改项目阅读器以返回对象列表,并改变项目处理器以接受列表作为输入。 如何对项目阅读器进行编码?

  • 我是新来的Spring批我有一个大的主表。这个主表被合并到5个单独的表中。我的要求是我需要创建一个编写器,它将写入这5个单独的表。但这些写入程序将根据以下条件调用:例如:如果我有一个未在主表中设置的字段,我将调用2个写入程序并跳过其他3个写入程序。 我使用带有分类器的复合写入器来检查条件,但分类器只返回1个写入器。分类器可以返回多个作家吗?或者有其他类可以满足我的要求吗?

  • 到目前为止,我正在运行spring批处理,只有一个作业。现在我想运行多个不同的作业,这意味着不同的功能。在我的配置文件中,我配置了两个具有不同id和不同名称的作业。现在我得负责这些工作。你能告诉我怎么跑吗。在这里,我的疑问是在我的java类中,我已经为运行批处理编写了这段代码。 对于其他作业,如何调用jobLauncher的run方法。 我的配置文件是