简体   繁体   中英

Setting a properties file in Spring Batch via a JobParameter

I have three different .properties files in a Spring Batch project, and I'm trying to set which .properties file should be used as a JobParameter. I'd like to be able to run the job like so:

java CommandLineJobRunner context.xml jobName region=us

The region should specify which .properties file should be used. The problem is getting the context to recognize the JobParameter. I've tried the following to no avail:

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

And also:

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

I had heard that adding scope="step" could fix similar issues, but I tried adding that to both of the above solutions and still had exceptions.

I think I'm missing a fundamental idea of why I can't get this working, but I'm unable to figure out what that idea is.

If anyone has any suggestions on getting this working and/or explaining why my previous approaches failed, I'd appreciate it.

This is not the right way to proceed (it is impossible do what you are trying to do).
You have to think that jobParameters is available only when a job is running and only for its composing steps marked with scope="step" (and not <context:property-placeholder> nor <util:properties> has a step attribute).
A way for solving the problem is to load properties file in job's execution context before first step is running with a listener:

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);
  }
}

in your 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>

and register this listener in your first step (you can't do that in your JobExectionListsner.beforeJob() because there isn't a scope="job" for now and late-binding of #{jobParameters['region']} value is not available).

To access your data with spEL use this syntax:

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

or a better syntax to access properties (IDK spEL so good, sorry).

Hope to be clear and can help to solve your problem.

EDIT (full code of my working 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" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM