在作业中使用 CommandLineJobRunner 参数 XML

Utilize CommandLineJobRunner parameters in job XML

我想我在这里遗漏了一些非常基本的东西。我有一个 spring-batch 批处理作业,我正在修改以在作业 运行 上接收参数,允许将临时文件存储在每个作业的时间戳 运行 临时文件夹中。目前所有临时文件都位于同一个文件夹中,如果作业 运行 不连续,临时文件会相互崩溃。

我有一个作业 运行ner bat 文件,我用它来实际启动作业,它正在创建时间戳并将其附加到传递给 CommandLineJobRunner 的参数中。所以它 运行s CommandLineJobRunner.main(args) 有 3 个参数:

String[] args = new String[]{[File.XML], [JobName], build.timestamp=[timestamp]}
CommandLineJobRunner.main(args)

在我的 XML 我有以下内容

<bean id="tempfiledir" class="org.springframework.core.io.FileSystemResource">
    <constructor-arg value="${batch.file.drive}:/${batch.file.writer.input.root.directory}/${batch.input_file}/${build.timestamp}" />
</bean> 

我的 batch.properties 文件中设置了其他变量。它们显然是静态的。

从那里,我像这样将资源传递到 bean 中:

<bean id="[beanTaskletID]" class="[taskletDir]">
    <property name="temporaryFilesDir" ref="tempfiledir"/>
</bean>

然后在实际步骤中我有:

<step id="[stepID]">
        <tasklet ref="[beanTaskletID]"/>
        <next on="FAILED" to="[failStepID]"/>
        <next on="COMPLETED" to="[completeStepID]"/>
    </step>

在我的 tasklet 中,我正在获取传递的参数,如下所示:

Resource tempDirectory;
public void setTemporaryFilesDir(Resource temporaryFilesDir) {
    this.tempDirectory = temporaryFilesDir;
}

当我尝试 运行 时,出现以下错误:

lassPathXmlApplicationContext [WARN] Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'tempfiledir' defined in class path resource [XML FILE]: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"
at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:211)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.processProperties(PropertySourcesPlaceholderConfigurer.java:180)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(PropertySourcesPlaceholderConfigurer.java:155)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:265)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:162)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:290)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:590)
    at com.batch.myJobRunner.main(myJobRunner.java:28)
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204)
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:178)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:175)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveStringValue(BeanDefinitionVisitor.java:282)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitGenericArgumentValues(BeanDefinitionVisitor.java:159)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitBeanDefinition(BeanDefinitionVisitor.java:85)
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:208)
    ... 11 more
2020-02-14 15:49:36 CommandLineJobRunner [ERROR] Job Terminated in error: Invalid bean definition with name 'tempfiledir' defined in class path resource [XML FILE]: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.nput_file}/${build.timestamp}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'tempfiledir' defined in class path resource [XML FILE]: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:211)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.processProperties(PropertySourcesPlaceholderConfigurer.java:180)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(PropertySourcesPlaceholderConfigurer.java:155)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:265)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:162)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:290)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:590)
    at com.batch.myJobRunner.main(myJobRunner.java:28)
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'build.timestamp' in string value "${batch.file.drive}:/${batch.file.writer.input.root.directory}${batch.input_file}/${build.timestamp}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204)
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:178)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:175)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveStringValue(BeanDefinitionVisitor.java:282)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveValue(BeanDefinitionVisitor.java:204)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitGenericArgumentValues(BeanDefinitionVisitor.java:159)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitBeanDefinition(BeanDefinitionVisitor.java:85)
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:208)
    ... 11 more

我想也许我需要为正在设置的参数声明占位符,所以我将以下内容添加到 batch.properties:

build.timestamp=

我读到在 运行 上传入的作业参数将覆盖同一参数的任何属性文件设置。但是当我 运行 这样的工作时, build.timestamp 总是只是一个空字符串。因此,要么不是这种情况,要么作业 运行 中传入的参数实际上并未在任何地方设置。

或者,或者我只是非常清楚地不知道如何从 XML 文件中的作业 运行 访问传入的参数。任何有关如何执行此操作的帮助将不胜感激。我花了几个小时来研究 spring-batch 文档,但没有任何内容清楚地表明如何访问 XML 文件中的参数,所做的只是注意到你 can 做吧。我找到的所有用于访问此类参数的文档都通过在 java 中创建作业而不是将其存放在 XML 中成功地工作。显然,这不是我处理此批处理作业的方法。

您可以使用 Spring 表达式语言访问作业参数。

#{jobParameters['build.timestamp']}

所以bean的定义会是这样的。由于您正在使用文件系统资源,因此您可以直接将文件注入 beanTaskletID。所以不需要单独定义tempfiledir bean。不要忘记添加范围步骤。

 <bean id="[beanTaskletID]" class="[taskletDir]" scope="step">
        <property name="temporaryFilesDir" value="file:${batch.file.drive}:/${batch.file.writer.input.root.directory}/${batch.input_file}/#{jobParameters['build.timestamp']}"/>
    </bean>