Настройка файла свойств в Spring Batch через JobParameter

65
7

У меня есть три разных файла.properties в проекте Spring Batch, и я пытаюсь установить, какой файл.properties следует использовать как JobParameter. Я хотел бы иметь возможность запускать работу следующим образом:

java CommandLineJobRunner context.xml jobName region=us

Регион должен указать, какой файл.properties должен использоваться. Проблема заключается в том, чтобы контекст распознал JobParameter. Я пробовал следующее безрезультатно:

<context:property-placeholder location="classpath:batch.#{jobParameters['region']}.properties"/>

А также:

<util:properties id="batchProperties" location="classpath:batch.#{jobParameters['region']}.properties"></util:properties>

Я слышал, что добавление scope = "step" может исправить подобные проблемы, но я попытался добавить это к обоим вышеупомянутым решениям и все еще имел исключения.

Я думаю, что мне не хватает фундаментальной идеи о том, почему я не могу заставить это работать, но я не могу понять, что это за идея.

Если у кого-то есть предложения по тому, как это будет работать и/или объяснить, почему мои предыдущие подходы не удались, я был бы признателен.

спросил(а) 2021-01-19T15:32:08+03:00 9 месяцев, 1 неделя назад
1
Решение
103

Это не правильный путь (вы не можете делать то, что вы пытаетесь сделать).
Вы должны думать, что параметры jobParameters доступны только в том случае, если задание выполняется, и только для его шагов компоновки, помеченных с помощью scope="step" (а не <context:property-placeholder> а не <util:properties> имеет атрибут step.
Способом решения проблемы является загрузка файла свойств в контексте выполнения задания перед первым шагом с прослушивателем:

public class PropertyLoaderJobExecutionListener extends StepExecutionListenerSupport {
Properties countryProperties;

public void setCountryProperties(Properties pfb) {
this.countryProperties = pfb;
}

@Override
public void beforeStep(StepExecution stepExecution) {
super.beforeStep(stepExecution);
// Store property file content in jobExecutionContext with name "batchProperties"
stepExecution.getJobExecution().getExecutionContext().put("batchProperties", countryProperties);
}
}

в вашем job.xml

<bean id="loadPropertiesListener" class="PropertyLoaderJobExecutionListener" scope="step">
<property name="pfb">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:batch.#{jobParameters['region']}.properties" />
</bean>
</property>
</bean>

и зарегистрируйте этого слушателя на первом шаге (вы не можете сделать это в своем JobExectionListsner.beforeJob() потому что на данный момент не существует scope="job" и поздняя привязка значения #{jobParameters['region']} недоступно).

Для доступа к данным с помощью spel используйте этот синтаксис:

#{jobExecutionContext.get('batchProperties').getProperty('language')}

или лучший синтаксис для доступа к свойствам (IDK spel так хорошо, извините).

Надеюсь быть ясным и может помочь решить вашу проблему.

EDIT (полный код моей работы job.xml):

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-util-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<job id="sourceJob" xmlns="http://www.springframework.org/schema/batch">
<step id="step1">
<tasklet ref="getRemoteFileTasklet" />
<listeners>
<listener ref="loadPropertiesListener" />
</listeners>
</step>
</job>
<bean id="loadPropertiesListener" class="PropertyLoaderJobExecutionListener" scope="step">
<property name="pfb">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:batch.#{jobParameters['region']}.properties" />
</bean>
</property>
</bean>
<bean id="getRemoteFileTasklet" class="GetRemoteFileTasklet" />

ответил(а) 2021-01-19T15:32:08+03:00 9 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема