2014-07-25 42 views
0

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

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的配置对于每个批处理作业都不同,因为它们正在读取不同的文件,但上面更明显的是,每个作业中应用的处理是不同的。第一批作业根据名称和部门筛选出一些记录,而第二批作业根据名称和城市筛选出一些记录。

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

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

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

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

也许我只是错过了一些简单的方法来配置每个作业,使它与其他作业分开存在?

回答

1

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

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

+0

非常感谢!我在Spring Batch文档中看到了这个概念,现在它更有意义。关于它现在的工作方式的一个好处是我相信你可以创建一个CommonBatchConfig。groovy'文件与常见的bean定义,将在所有其他配置共享,这是很方便。我以前曾尝试通过'importBeans'来做到这一点,但无法使其工作。 Grails插件可以按文件顺序解析bean,这样通用文件可能不得不被命名为'AAA_CommonBatchConfig.groovy'。还没有尝试过。 –

相关问题