Как отправить пользовательский объект в качестве параметра задания в Spring Batch?
У меня есть требование отправить пользовательский объект в пакетное задание Spring, где этот объект постоянно используется обработчиком элементов для бизнес-требований.
Как мы можем отправить пользовательский объект извне в контекст работы. Этот объект изменяется с задания на задание и генерируется во время выполнения в зависимости от бизнес-ситуации.
Как можно отправить это как параметр задания? или есть ли способ, которым я могу установить этот объект для соответствующего задания?
Может ли переопределение Spring JobParameter помочь мне в любом случае? или есть какие-то большие проблемы в результате этого доминирующего поведения?
5 ответов
Используйте приведенный ниже класс для отправки 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;
}
}
===========================
Использование:
Параметр отправки:
JobParameters paramJobParameters = new JobParametersBuilder().addParameter("customparam", new CustomJobParameter<MyClass>(myClassReference)).toJobParameters();
Получение параметра:
MyClass myclass = (MyClass)jobExecution.getJobParameters().getParameters().get("customparam").getValue();
Я суммировал причины, по которым вы не можете отправить объект как JobParameter
в этом вопросе. Есть несколько идей по этому вопросу, как вы можете это сделать.
TL: TR: Я думаю, что лучшим способом было бы либо создать таблицу в БД, которая хранит Object и передать идентификатор этой записи как JobParameter, либо сериализовать Object в json и передать его как String в задании в качестве JobParameter. Если вы выбираете второй вариант, имейте в виду, что string_val хранится в БД как varchar 250, поэтому ограничение составляет 250 символов.
Этот вопрос был задан на официальном форуме Spring Batch: http://forum.spring.io/forum/spring-projects/batch/96660-how-to-pass-complex-objects-to-job-launcher
Джира была открыта тогда, но разработчики решили не решать ее (Won't fix
): https://jira.spring.io/browse/BATCH-966
Здесь обсуждалось альтернативное решение для более или менее идентичного случая (передача потока в качестве JobParameter): передача потока в задание в качестве параметра
Подводя итог, можно сказать, что нет ответа: вы можете передавать только примитивные типы в качестве JobParameters, а переопределение кажется нежелательным. Альтернативные решения - объявить и внедрить Бин с вашими параметрами или использовать статическую переменную для доступа к нему в рамках всего проекта.
Я нашел способ, только если длина вашего строкового параметра фиксирована, но она больше 250. Просто разделите его на части по 250, затем в конфигурации XML используйте Spring EL следующим образом:
Установите ваш параметр в вашем основном классе следующим образом:
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()));
Настройте свои параметры и область действия в "шаг":
<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>
Надеюсь, поможет.
Вы должны использовать ThreadLocal перед началом выполнения задания, на испанском языке есть учебное пособие о том, как использовать ThreadLocal: