通过Spring Batch作业步骤维护作业前对象

时间:2016-06-02 20:48:05

标签: java spring list spring-batch autowired

对于我的批处理应用程序,我在执行Spring Batch作业之前需要执行一些步骤。例如,我需要执行特定查询并将数据存储在属性中 - 具有复杂类型的列表(List<ComplexType>) - 以便可以在整个Spring Batch作业中使用和操作它(主要在ItemReader中)

我已尝试在列表中自动装配并在步骤中访问它,但我无法以这种方式访问​​列表中的数据。无论在作业之前添加到我的自动装配的List属性中的值是什么值,我的列表中都会得到一个null ComplexType。

我也尝试了passing data using ExecutionContext,但我认为这不应该在Spring Batch作业执行之外工作。

我想知道的是,在执行Spring Batch作业之前填充项目的最佳方法是什么,并在作业的整个生命周期内维护该对象。

如果最好的方法是我之前的尝试之一,那么对这些方法的常见错误的任何指导都表示赞赏,谢谢。

2 个答案:

答案 0 :(得分:0)

你可以这样做:) 尝试在作业参数增量技巧中执行此操作:

<j:job id="Your_job"  incrementer="incrementerBean">

<bean id="incrementerBean" class="com.whatever.IncrementerClass"/>

增量级:

class IncrementerClass implements JobParametersIncrementer { 

  @Override
  JobParameters getNext(JobParameters parameters) {

    Map<String, JobParameter> map = new HashMap<String, JobParameter>(
    parameters.getParameters());
    ...
    //you can put here your list, if it can be :
    // Domain representation of a parameter to a batch job. Only the following types
    // can be parameters: String, Long, Date, and Double.

    //make some query 

    List<String> listStrings = Query.getYourQuery();

        //Join your query into string to have something like this below

        map.put("listOfSomething", new JobParameter("abc, abc, abc"));
        ...

     return new JobParameters(map);
  }


}

这就是全部, 那么你可以在一些处理bean中使用这个参数:

  @Value("#{jobParameters['listOfSomething']}")
  private String yourList

您可以从字符串构建列表,这就是全部:) 祝你好运

答案 1 :(得分:0)

感谢JobExecutionListener指针StepExecutionListener。我最终创建了自己的public class CustomStepListener implements StepExecutionListener { @Autowired private CustomObject customObject; @Override public void beforeStep(StepExecution stepExecution) { // initialize customObject and do other pre set setup } @Override public ExitStatus afterStep(StepExecution stepExecution) { return null; } ,我的预处理将在那里进行。

我跟着Luca Basso Ricci,它遍历不同类型的Spring Batch Listeners。

我在Java代码中创建了一个像这样的自定义侦听器:

CustomObject

我在这里初始化了自动装配的CustomObject课程。 List类是一个自定义对象,其中只包含ComplexType类型@Component public class CustomObject { private List<ComplexType> customObjectList; public List<ComplexType> getCustomObjectList() { return customObjectList; } public void setCustomObjectList(List<ComplexType> customObjectList) { this.customObjectList= customObjectList; } }

<!-- ... -->
<beans:bean id="customStepListener" 
        class="com.robotsquidward.CustomStepListener"/>

<job id="robotsquidwardJob"
    job-repository="jobRepository"
    incrementer="runIdIncrementer">
    <step id="robotsquidwardStep">
        <tasklet task-executor="taskExecutor" throttle-limit="1">
            <chunk 
                reader="robotsquidwardReader" 
                processor="robotsquidwardProcessor"
                writer="robotsquidwardWriter"
                commit-interval="1"/>
        </tasklet>
        <listeners>
            <listener ref="customStepListener"/>
        </listeners>
    </step>
</job>

最后,在我的工作配置&batch-job-context.xml&#39;我添加了我的新听众:

ComplexObject

当我按照这些步骤操作时,我可以在List函数中初始化beforeJob ComplexObject并访问我内List @Component @Scope(value = "step") public class RobotsquidwardReader implements ItemReader<ComplexType> { @Autowired private CustomObject customObject; @Override public ComplexType read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { if(customObject.getCustomObjectList() != null) { return customObject.getCustomObjectList.remove(0); } else { return null; } } } 的值工作的读者课程:

<script>
var canvas=null;
var context=null;
setup=function(){
    canvas=document.getElementById("my_canvas");
    context=canvas.getContext('2d');
    canvas.width=1200;
    canvas.height=720;
    img=new Image();
    img.onload=onImageLoad;
    img.src="http://imgge.bg.ac.rs/images/logo1.jpg";
    context.drawImage(img,192,192);
    };
    onImageLoad=function(){
        document.write("done !!");
        context.drawImage(img,155,10);
    };
setup();
</script>

很容易。所需要的只是两个新类,一个配置更改,一个主要的头痛:)