为什么这个 Spring Batch Bean 没有自动连接到 Grails 中?
Why is this Spring Batch Bean not auto wired in Grails?
我不确定为什么我的 delegate
bean 没有被连接并且为空。请问有人可以给点建议吗?
在ScheduleJobBatchConfig.groovy内:
beans {
xmlns batch:"http://www.springframework.org/schema/batch"
batch.job(id: 'scheduleJob', restartable: true) {
batch.step(id: 'scheduleStep1') {
batch.tasklet {
batch.chunk(
reader: 'scheduleReaderWrapper',
writer: 'scheduleWriter',
'commit-interval': 50
)
}
}
}
scheduleReaderWrapper(ScheduleReaderWrapper) { bean ->
bean.autowire = 'byName'
delegate = ref('basicScheduleReader') // this is null
}
basicScheduleReader(FlatFileItemReader) { bean ->
bean.scope = 'step'
resource = "#{jobParameters['file']}"
lineMapper = ref('scheduleLineMapper')
}
// more sub-beans here
}
这是未连接的 bean(在 src/groovy 内):
public class ScheduleReaderWrapper implements ItemStreamReader<Object> {
private ItemStreamReader<Object> delegate;
public Object read() throws Exception {
// do some reading here
return schedule;
}
public void setDelegate(ItemStreamReader<Object> delegate) {
this.delegate = delegate;
}
public void close() throws ItemStreamException {
delegate.close();
}
public void open(ExecutionContext arg0) throws ItemStreamException {
delegate.open(arg0);
}
public void update(ExecutionContext arg0) throws ItemStreamException {
delegate.update(arg0);
}
}
所有闭包都有一个可设置的 delegate
属性 通过 setDelegate
和 getDelegate
方法。这在实现 DSL 时经常使用。
此代码作为注册 bean 定义的方法调用被调用:
scheduleReaderWrapper(ScheduleReaderWrapper) { bean ->
bean.autowire = 'byName'
delegate = ref('basicScheduleReader')
}
它与 void beanName(Class c, Closure c) { ... }
基本相同,它使用 Groovy 中的能力将闭包留在方法参数之外。显然没有 scheduleReaderWrapper
方法,但是 DSL 委托(bean 构建器)处理丢失的方法异常并使用方法名称作为 bean 名称,并且由于第一个 arg 是 Class 它用作bean class,可选的第二个 arg 是闭包,因此调用它来自定义 bean 属性。
bean 构建器依赖于调用不存在的方法以及获取和设置不存在的属性,因此它会收到这些调用的通知并且可以使用 method/property 名称和参数来配置 bean。
这个
delegate = ref('basicScheduleReader')
相当于
setDelegate(ref('basicScheduleReader'))
但它是在一个闭包内调用的,闭包有一个 setDelegate
方法。如果它使用闭包 class 中不存在的任何其他 属性 名称,它将触发丢失的 属性 异常,并被解释为设置 属性 的调用在 ScheduleReaderWrapper
实例上,同时由 Spring.
配置
例如,如果您将 ScheduleReaderWrapper
中的 属性 更改为 wrappedReader
,它将按预期工作:
wrappedReader = ref('basicScheduleReader')
我不确定为什么我的 delegate
bean 没有被连接并且为空。请问有人可以给点建议吗?
在ScheduleJobBatchConfig.groovy内:
beans {
xmlns batch:"http://www.springframework.org/schema/batch"
batch.job(id: 'scheduleJob', restartable: true) {
batch.step(id: 'scheduleStep1') {
batch.tasklet {
batch.chunk(
reader: 'scheduleReaderWrapper',
writer: 'scheduleWriter',
'commit-interval': 50
)
}
}
}
scheduleReaderWrapper(ScheduleReaderWrapper) { bean ->
bean.autowire = 'byName'
delegate = ref('basicScheduleReader') // this is null
}
basicScheduleReader(FlatFileItemReader) { bean ->
bean.scope = 'step'
resource = "#{jobParameters['file']}"
lineMapper = ref('scheduleLineMapper')
}
// more sub-beans here
}
这是未连接的 bean(在 src/groovy 内):
public class ScheduleReaderWrapper implements ItemStreamReader<Object> {
private ItemStreamReader<Object> delegate;
public Object read() throws Exception {
// do some reading here
return schedule;
}
public void setDelegate(ItemStreamReader<Object> delegate) {
this.delegate = delegate;
}
public void close() throws ItemStreamException {
delegate.close();
}
public void open(ExecutionContext arg0) throws ItemStreamException {
delegate.open(arg0);
}
public void update(ExecutionContext arg0) throws ItemStreamException {
delegate.update(arg0);
}
}
所有闭包都有一个可设置的 delegate
属性 通过 setDelegate
和 getDelegate
方法。这在实现 DSL 时经常使用。
此代码作为注册 bean 定义的方法调用被调用:
scheduleReaderWrapper(ScheduleReaderWrapper) { bean ->
bean.autowire = 'byName'
delegate = ref('basicScheduleReader')
}
它与 void beanName(Class c, Closure c) { ... }
基本相同,它使用 Groovy 中的能力将闭包留在方法参数之外。显然没有 scheduleReaderWrapper
方法,但是 DSL 委托(bean 构建器)处理丢失的方法异常并使用方法名称作为 bean 名称,并且由于第一个 arg 是 Class 它用作bean class,可选的第二个 arg 是闭包,因此调用它来自定义 bean 属性。
bean 构建器依赖于调用不存在的方法以及获取和设置不存在的属性,因此它会收到这些调用的通知并且可以使用 method/property 名称和参数来配置 bean。
这个
delegate = ref('basicScheduleReader')
相当于
setDelegate(ref('basicScheduleReader'))
但它是在一个闭包内调用的,闭包有一个 setDelegate
方法。如果它使用闭包 class 中不存在的任何其他 属性 名称,它将触发丢失的 属性 异常,并被解释为设置 属性 的调用在 ScheduleReaderWrapper
实例上,同时由 Spring.
例如,如果您将 ScheduleReaderWrapper
中的 属性 更改为 wrappedReader
,它将按预期工作:
wrappedReader = ref('basicScheduleReader')