java - 在作业 XML 中使用 CommandLineJobRunner 参数
问题描述
我相信我在这里遗漏了一些非常基本的东西。我有一个 spring-batch 批处理作业,我正在修改以在作业运行时接受一个参数,以允许将临时文件存储在每个作业运行临时文件夹中的时间戳中。目前所有临时文件都位于同一个文件夹中,如果作业不按顺序运行,临时文件会相互碰撞。
我有一个作业运行器 bat 文件,用于实际启动作业,它正在创建一个时间戳并将其附加到传递给 CommandLineJobRunner 的参数中。因此它使用 3 个参数运行 CommandLineJobRunner.main(args):
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$2.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$2.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 文件中的参数,所有它所做的只是说明你可以做到。我找到的所有用于访问此类参数的文档都是通过在 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>
推荐阅读
- c - 如何在通过本机消息传递 API 发送的 Web 扩展 JSON 的消息长度不确定的情况下调试 C 中的错误?
- api - 在 Instagram Graph API 上获取 Instagram Business 帐户 ID 的错误消息
- design-patterns - 在后端设计无限滚动列表的最佳方法
- python - UnboundLocalError:分配前引用的局部变量“xd”
- python - 部署到heroku时,带有gunicorn和容器堆栈的Django应用程序未运行
- opengl - 将统一缓冲区对象与 glMultiDrawElementsIndirect 一起使用的最佳方法是什么?
- go - 如何将 2d 数组分配给 golang 中的地图持有的另一个 2d 数组?
- html - 我不明白 W3C Unicorn 测试仪中的这些错误,它们是什么意思?
- javascript - webpack devserver build project but not refresh the browser
- jquery - 如何使用 rails 和 jquery 优化 ajax 搜索