how to send a custom object as Job Parameter in Sp

2019-03-30 20:53发布

问题:

I have a requirement of sending a Custom Object to the Spring Batch Job , where this Object is used continuously used by the Item Processor for the business requirement.

How can we send custom object from outside to the Job Context. This Object changes from Job to Job and generated at runtime depending on Business case.

How can send this as a Job Parameter? or is there any way that i can set this Object to the respective Job ?

can overriding Spring JobParameter help me in any way? or are there any Big issues as an outcome of this Overriding behaviour ?

回答1:

This question has been asked on the offical Spring Batch forum : http://forum.spring.io/forum/spring-projects/batch/96660-how-to-pass-complex-objects-to-job-launcher

A Jira was open then but the developpers chose not to resolve it (Won't fix) : https://jira.spring.io/browse/BATCH-966

An alternative solution for a more or less identical case (passing a stream as a JobParameter) was discussed here : Passing stream to job as parameter


To summarize, the answer is no you can only pass primitive types as JobParameters and overriding it seems to be discouraged. The alternative solutions are to either declare and inject a Bean with your parameters or to use a static variable to access it project-wide.



回答2:

I have summarized reasons why you cannot send object as JobParameter in this question. There are couple of ideas on that question how you can do it.

TL:TR: I think best way would be either to create table in DB which stores Object and pass id of that record as JobParameter or to serialize Object to json and pass it as String in job as JobParameter. If you go with second option be aware that string_val is stored in DB as varchar 250 so limit is 250 characters.



回答3:

You would use ThreadLocal before init the job execution, there is a tutorial in spanish about how to use ThreadLocal:

http://aquiseprograma.co/2015/09/como-pasar-variables-o-valores-entre-metodos-sin-que-sea-como-parametro-dentro-del-mismo-hilo-de-ejecucion-en-java-threadlocal/



回答4:

I've found a way just if your string parameter length is fixed, but it is greater than 250. Just split it into pieces of 250, then, within the XML configuration use Spring EL in this way:

Set your parameter in your main Class like this:

JobParametersBuilder parametersBuilder = new JobParametersBuilder();
parametersBuilder.addString("useful.parameter.1", headers.substring(0, 250));
parametersBuilder.addString("useful.parameter.2", headers.substring(250, 500));
parametersBuilder.addString("useful.parameter.3", headers.substring(500, headers.length()));

Configure your parameters and the scope in "step":

<bean id="someStep01Writer" class="path.to.some.StepWriter" scope="step">
    <property name="someUsefulProperty" value="#{jobParameters['useful.parameter.1'] + jobParameters['useful.parameter.2'] + jobParameters['useful.parameter.3']}"/>
</bean>

Hope it helps.



回答5:

Use the below class to send CustomObject.

public static class CustomJobParameter<T extends Serializable> extends JobParameter {
        private T customParam;
        public CustomJobParameter(T customParam){
            super(UUID.randomUUID().toString());//This is to avoid duplicate JobInstance error
            this.customParam = customParam;
        }
        public T getValue(){
            return customParam;
        }
    }

===========================

Usage:

  1. Sending parameter:

    JobParameters paramJobParameters = new JobParametersBuilder().addParameter("customparam", new CustomJobParameter<MyClass>(myClassReference)).toJobParameters();

  2. Retrieving parameter:

    MyClass myclass = (MyClass)jobExecution.getJobParameters().getParameters().get("customparam").getValue();