为什么这个Spring Batch Bean没有在Grails中自动连线?

时间:2015-02-28 00:29:01

标签: grails spring-batch

我不确定为什么我的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);
    }
}

1 个答案:

答案 0 :(得分:1)

所有闭包都通过delegatesetDelegate方法具有可设置的getDelegate属性。这通常在实现DSL时使用。

此代码作为注册bean定义的方法调用调用:

scheduleReaderWrapper(ScheduleReaderWrapper) { bean ->
    bean.autowire = 'byName'
    delegate = ref('basicScheduleReader')
}

它与void beanName(Class c, Closure c) { ... }基本相同,并且它使用Groovy中的函数将闭包留在方法args之外。显然没有scheduleReaderWrapper方法,但DSL委托(bean构建器)处理缺少的方法异常并使用方法名称作为bean名称,并且因为第一个arg是一个类,所以它使用它作为bean类,并且可选的第二个arg是一个Closure,因此调用它来自定义bean属性。

bean构建器依赖于调用不存在的方法以及获取和设置不存在的属性,因此会通知这些调用,并可以使用方法/属性名称和args来配置bean。

delegate = ref('basicScheduleReader')

相当于

setDelegate(ref('basicScheduleReader'))

但是它在一个闭包内调用,它有一个setDelegate方法。如果它使用了Closure类中不存在的任何其他属性名称,它将触发缺少的属性异常,并被解释为在ScheduleReaderWrapper实例上由Spring配置时调用该属性。 / p>

例如,如果您将ScheduleReaderWrapper中的属性更改为wrappedReader,它将按预期工作:

wrappedReader = ref('basicScheduleReader')