Java 如何确保MultiResourceItemReader在每次执行作业时刷新资源
我有一个java应用程序,它利用spring任务调度和批处理作业。我依靠Java 如何确保MultiResourceItemReader在每次执行作业时刷新资源,java,spring,scheduled-tasks,task,Java,Spring,Scheduled Tasks,Task,我有一个java应用程序,它利用spring任务调度和批处理作业。我依靠job中的MultiResourceItemReader从目录中读取一些文件,处理它们,然后删除这些文件。外部进程负责定期将新文件放入该目录。但问题是,每次运行作业时,它都会尝试读取启动应用程序时存在的相同文件资源,因此失败,因为这些资源已经消失,而现在又有了新文件 问题是,如何配置应用程序,以便针对给定作业的每次计划执行评估resources属性 相关的豆子粘贴在下面: <bean id="multiResour
job
中的MultiResourceItemReader
从目录中读取一些文件,处理它们,然后删除这些文件。外部进程负责定期将新文件放入该目录。但问题是,每次运行作业时,它都会尝试读取启动应用程序时存在的相同文件资源,因此失败,因为这些资源已经消失,而现在又有了新文件
问题是,如何配置应用程序,以便针对给定作业的每次计划执行评估resources属性
相关的豆子粘贴在下面:
<bean id="multiResourceReader" class="org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources" value="file:/opt/data/*.csv" />
<property name="delegate" ref="testFlatFileItemReader" />
</bean>
<batch:job id="MyJob">
<batch:step id="readandstore">
<batch:tasklet>
<batch:chunk reader="multiResourceReader" writer="oracleItemWriter" commit-interval="10" />
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="runScheduler" class="com.myapp.Scheduler">
<property name="jobLauncher" ref="jobLauncher" />
<property name="job" ref="MyJob" />
</bean>
<task:scheduled-tasks>
<task:scheduled ref="runScheduler" method="run" cron="*/30 * * * * *" />
</task:scheduled-tasks>
我设法解决了我自己发布的问题,因为几乎一周没有收到任何回复
我删除了multiResourceReader
的resources属性,并在
下的侦听器中添加了一个StepListener
,该侦听器实现了StepExecutionListener
。此侦听器有两个方法,一个在步骤执行之前调用,另一个在步骤执行之后调用。StepListener
接受一个名为filePattern
的属性,该属性的值类似于您以前为multiResourceReader
的resources属性提供的值。以下是更新后的bean的外观:
<batch:job id="MyJob">
<batch:step id="readandstore">
<batch:tasklet>
<batch:chunk reader="multiResourceReader" writer="oracleItemWriter" commit-interval="10" />
<batch:listeners>
<batch:listener ref="StepListener" />
</batch:listeners>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="multiResourceReader" class="org.springframework.batch.item.file.MultiResourceItemReader">
<property name="delegate" ref="csvFileItemReader" />
</bean>
<bean id="StepListener" class="com.myapp.StepListener">
<property name="filePattern" value="file:/opt/data/*.csv" />
</bean>
bean multiResourceReader的作用域是单例的,因此每个作用域只创建1个。当这个bean被创建时,资源的价值就被解析了
如果您将bean multiResourceReader的作用域设置为step,那么它也应该解决您的问题。然后每次执行步骤时都会创建一个新bean。尝试在名为“multiResourceReader”的配置bean中添加标记“step”:
我也遇到过同样的问题,但我用另一种方法解决了,可能会有帮助,我正在使用FlatFileItemReader,但问题是一样的
解决方案是使用属性资源中的ref和处理jobParams的bean,这样每次步骤重新开始时,它都是一个新实例,具有新值,下面的代码就是我如何执行的:
<bean id="customFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" ref="customFile"/><!-- avoid use directly jobParams here -->
<property name="linesToSkip" value="0" />
<property name="encoding" value="ISO-8859-1" />
<property name="comments" value="*, \u001A" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="br.com.sample.batch.CustomFieldSetMapperSIAW"/>
</property>
</bean>
</property>
另一个选项是在调用super.open()
方法之前,扩展MultiResourceItemReader
并重写open()
方法并调用setResources()
public class CustomMultiItemReader<T> extends MultiResourceItemReader<T> {
private static final Log logger = LogFactory.getLog(PrestoMultiItemReader.class);
private String filePattern;
public CustomMultiItemReader() {
super();
}
@Override
public void open(ExecutionContext executionContext) {
Assert.notNull(filePattern, "filePattern must be set");
try {
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = patternResolver.getResources(filePattern);
super.setResources(resources);
} catch (IOException e) {
logger.error("No resources to read.", e);
}
super.open(executionContext);
}
public void setFilePattern(String filePattern) {
this.filePattern = filePattern;
}
}
我发现这确实是真的,但是您需要将资源定义为显式属性,如果您使用“p”名称空间定义资源属性,那么即使bean是步骤范围的,也不会重新加载资源。
<bean id="customFile" class="org.springframework.core.io.FileSystemResource" scope="step">
<constructor-arg value="#{jobParameters[arquivoGSIN]}"></constructor-arg>
public class CustomMultiItemReader<T> extends MultiResourceItemReader<T> {
private static final Log logger = LogFactory.getLog(PrestoMultiItemReader.class);
private String filePattern;
public CustomMultiItemReader() {
super();
}
@Override
public void open(ExecutionContext executionContext) {
Assert.notNull(filePattern, "filePattern must be set");
try {
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = patternResolver.getResources(filePattern);
super.setResources(resources);
} catch (IOException e) {
logger.error("No resources to read.", e);
}
super.open(executionContext);
}
public void setFilePattern(String filePattern) {
this.filePattern = filePattern;
}
}
public CustomMultiItemReader<T> customMultiItemReader() {
String filePattern = "file:/...";
CustomMultiItemReader<T> reader = new CustomMultiItemReader<T>();
reader.setDelegate(reader()); //reader to delegate here
reader.setFilePattern(filePattern);
reader.setStrict(true);
return reader;
}