问题
Below is the job file currently i'm using.
<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>
回答1:
As was said in the Luca's comment, you can use a ClassifierCompositeItemWriter which needs a org.springframework.classify.Classifier.
One of the few implementations of the latter is org.springframework.classify.BackToBackPatternClassifier which takes in turn a routerDelegate and a matcherMap.
The routerDelegate is a bean which will have a method annotated with @Classifier. This method will take an Object and return a String. This string will then be matched against the values you declare in your module-context, and call an ItemWriter accordingly.
Here's an example :
<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>
And here's what a Classifier looks like (this one is a Generic classifier using Reflect API to call a method passed as an argument on an object) :
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;
}
}
This classifier is used this way, where YourMethod is a public method of the class of the Object to be classified (without the parenthesis) :
<bean class="xx.xx.xx.GenericClassifier">
<property name="methodName" value="YourMethod"></property>
</bean>
The value String returned by the Classifier is then matched with the key of the according entry of the matcherMap.
回答2:
Forgot to add solution that I found. Below solution worked for me. Compiled the Code and it's working fine.
First, you will need a Classifier. Either implement the Classifier interface or annotate classify() method with @Classifier.
Here I have used annotation.
public class MyClassifier
{
@Classifier public String classify(Policy pol)
{
return pol.getPolCode;// returns "01", "02"
}
}
Add a Classifier 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>
Add your writer bean as like below
<bean id="ItemWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
<property name="myClassifier" ref="myClassifier" />
</bean>
The Above Code may throw WriterNotOpenException. For this you need to add batch:stream to the step.
<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>
来源:https://stackoverflow.com/questions/33330171/how-to-configure-a-spring-batch-job-with-single-reader-and-calling-multiple-writ