一个Grails应用程序中的多个Spring Batch作业

时间:2014-07-25 01:26:21

标签: grails spring-batch

我有一个Grails应用程序,它使用SpringBatch插件来控制将文件批量加载到数据库中。我在一个Grails应用程序中有两个批处理配置,让我们称它们为OneBatchConfig.groovyTwoBatchConfig.groovy。他们做了非常相似的事情,只是略有不同的处理。例如:

OneBatchConfig.groovy

beans {
    xmlns batch:"http://www.springframework.org/schema/batch"

    batch.job(id: "batchJob1") {
        batch.step(id: 'loadFile') {
            batch.tasklet {
                batch.chunk(
                    reader:    'fileReader',
                    processor: 'compositeProcessor',
                    writer:    'dbWriter')
                }
            }
        }

        // Ignore the fileReader and dbWriter for now

        compositeProcessor(CompositeItemProcessor) {
            delegates = [
                ref('filterInvalidNames'),
                ref('filterInvalidDepartments')
            ]
        }

        // Ignore the details of the filter* processors
    }
}

TwoBatchConfig.groovy

beans {
    xmlns batch:"http://www.springframework.org/schema/batch"

    batch.job(id: "batchJob2") {
        batch.step(id: 'loadFile') {
            batch.tasklet {
                batch.chunk(
                    reader:    'fileReader',
                    processor: 'compositeProcessor',
                    writer:    'dbWriter')
                }
            }
        }

        // Ignore the fileReader and dbWriter for now

        compositeProcessor(CompositeItemProcessor) {
            delegates = [
                ref('filterInvalidNames'),
                ref('filterInvalidCities')
            ]
        }

        // Ignore the details of the filter* processors
    }
}

两个批处理作业都读入文件,执行一些处理,并将结果保存到数据库。 fileReader的配置对于每个批处理作业是不同的,例如,它们正在读取不同的文件,但上面更明显的是每个作业中应用的处理是不同的。第一个批处理作业根据名称和部门过滤掉一些记录,而第二个作业根据名称和城市过滤掉一些记录。

但是,这些过滤步骤是可配置的,因为第一个作业可能会过滤掉名称为“John”的记录,而第二个作业可能会过滤掉名称为“Steve”的记录。该配置位于批处理作业定义本身内部,而不是代码中。

所以我的问题是这样的:在我的测试中,似乎所有这两个*BatchConfig.groovy文件中定义的bean都是全局命名空间的一部分;包括步骤的名称。这意味着在loadFileOneBatchConfig.groovy中都有一个名为TwoBatchConfig.groovy的步骤是一个坏主意,在Grails应用程序之后只有一个这些步骤才真正存在启动。这也意味着filterInvalidNames bean只能存在一次,因此相同的过滤将应用于这两个作业(有些不可见)。

首先,这种理解是正确的吗?这是有道理的,考虑到其他bean如dataSource,只是可用而不必做任何事情。

但如果是这样,在单个Grails应用程序中管理大量*BatchConfig.groovy文件时,它也会造成一些破坏。除了要求在每个步骤中使用唯一名称以及在创建的所有*BatchConfig.groovy文件中使用每个bean之外,是否有其他解决方案?就像在每个batch.job块中的bean名称中应用某种命名空间的能力一样?

也许我只是错过了如何配置每个作业的简单方法,因此它与其他作业分开存在?

1 个答案:

答案 0 :(得分:1)

作业中的组件只是加载到全局Grails(Spring)上下文中的spring bean。这意味着您必须为您的组件提供全球唯一的名称。我只是在每个步骤前面加上作业名称,尽管这可以产生一些长bean名称。

如果您直接使用spring-batch,可以使用AutomaticJobRegistrar来解决这个问题。 Grails插件目前不会这样做。我已经在github上评论了您的问题以反映此请求。 https://github.com/johnrengelman/grails-spring-batch/issues/23