wsa*_*ams 5 java spring spring-batch
我试图创建使用Spring的批处理作业ListItemReader<String>,ItemProcessor<String, String>和ItemWriter<String>.
XML如下所示,
<job id="sourceJob" xmlns="http://www.springframework.org/schema/batch">
<step id="step1" next="step2">
<tasklet>
<chunk reader="svnSourceItemReader"
processor="metadataItemProcessor"
writer="metadataItemWriter"
commit-interval="1" />
</tasklet>
</step>
<step id="step2">
<tasklet ref="lastRevisionLoggerTasklet"></tasklet>
</step>
</job>
<bean id="svnSourceItemReader"
class="com.example.repository.batch.SvnSourceItemReader"
scope="prototype">
<constructor-arg index="0">
<list>
<value>doc1.xkbml</value>
<value>doc2.xkbml</value>
<value>doc3.xkbml</value>
</list>
</constructor-arg>
</bean>
<bean id="metadataItemProcessor"
class="com.example.repository.batch.MetadataItemProcessor"
scope="prototype" />
<bean id="metadataItemWriter"
class="com.example.repository.batch.MetadataItemWriter"
scope="prototype" />
Run Code Online (Sandbox Code Playgroud)
读者,处理者和作家都是香草,
public class SvnSourceItemReader extends ListItemReader<String> {
public SvnSourceItemReader(List<String> list) {
super(list);
System.out.println("Reading data list " + list);
}
@Override
public String read() {
String out = (String) super.read();
System.out.println("Reading data " + out);
return out;
}
}
public class MetadataItemProcessor implements ItemProcessor<String, String> {
@Override
public String process(String i) throws Exception {
System.out.println("Processing " + i + " : documentId " + documentId);
return i;
}
}
public class MetadataItemWriter implements ItemWriter<String> {
@Override
public void write(List<? extends String> list) throws Exception {
System.out.println("Writing " + list);
}
}
Run Code Online (Sandbox Code Playgroud)
这项工作就是这样开始的,但按照每10秒计划一次.
long nanoBits = System.nanoTime() % 1000000L;
if (nanoBits < 0) {
nanoBits *= -1;
}
String dateParam = new Date().toString() + System.currentTimeMillis()
+ "." + nanoBits;
param = new JobParametersBuilder().addString("date", dateParam)
.toJobParameters();
JobExecution execution = jobLauncher.run(job, param);
Run Code Online (Sandbox Code Playgroud)
当应用程序启动时,我看到它读取,处理并写入传递给阅读器的列表中的三个项目.
Reading data doc1.xkbml
Processing doc1.xkbml : documentId doc1
Writing [doc1.xkbml]
Reading data doc2.xkbml
Processing doc2.xkbml : documentId doc2
Writing [doc2.xkbml]
Reading data doc3.xkbml
Processing doc3.xkbml : documentId doc3
Writing [doc3.xkbml]
Run Code Online (Sandbox Code Playgroud)
因为这sourceJob是在计划的计时器上,每隔10秒我就会看到处理完该列表,但我会在所有后续运行中看到.
Reading data null
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会这样?我是Spring Batch的新手,无法解决问题.
谢谢/ w
Luc*_*cci 14
问题是你把你的读者标记为scope="prototype".它应该是scope="step".
在Spring-batch中只有两个范围:( singleton默认值)和step.
来自javadoc:
StepScope:
步骤上下文的范围.此范围内的对象使用Spring容器作为对象工厂,因此每个执行步骤只有一个这样的bean实例.此范围内的所有对象都是(无需修饰bean定义).
和
为了使用后期绑定,需要使用Step的范围,因为在Step开始之前实际上不能实例化bean,这允许找到属性.
在Spring上下文启动期间查看您的日志,您将看到以下行:
信息:在9毫秒内完成从类路径资源[org/springframework/batch/core/schema-hsqldb.sql]执行SQL脚本.
读取数据列表[doc1.xkbml,doc2.xkbml,doc3.xkbml]
正如您所看到的,您的读者已经被创建并作为单身人士进行管理; Spring-batch上下文中的动态bean应该使用特殊step范围进行管理,这样Spring每次执行一个步骤时都会创建bean的新副本.
在您的读者中,ListItemReader.read()写作:
public T read() {
if (!list.isEmpty()) {
return list.remove(0);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
在每个阅读项目从原始列表中删除!读者构造一次,在第二次作业执行时,列表为空!
| 归档时间: |
|
| 查看次数: |
21339 次 |
| 最近记录: |