从 Spring 作业配置中删除重复代码

Removing duplicate code from Spring job configuration

下面是我的步骤配置 -

<beans:bean id="myInputFileReader" class="com.rbos.fm.risk.batch.spring.reader.InputFileReader" scope="step">
        <beans:property name="delegate">
            <beans:bean class="org.springframework.batch.item.file.FlatFileItemReader"
                    scope="step">
                <beans:property name="resource" ref="inputFileSystemResource" />
                <beans:property name="linesToSkip" value="1" />
                <beans:property name="lineMapper">
                    <beans:bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                        <beans:property name="lineTokenizer">
                            <beans:bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                                <beans:property name="delimiter" value="|"/>
                            </beans:bean>
                        </beans:property>
                        <beans:property name="fieldSetMapper">
                            <beans:bean class="com.test.MyFieldMapper1" scope="prototype"/>
                        </beans:property>
                    </beans:bean>
                </beans:property>
            </beans:bean>
        </beans:property>
        <beans:property name="param1" value="#{jobParameters['param1']}"/>
        <beans:property name="param2" value="#{jobParameters['param2']}"/>
        <beans:property name="param3" value="#{jobParameters['param3']}"/>
    </beans:bean>


    <beans:bean id="fileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
        <beans:property name="resource" ref="outputFileSystemResource" />
        <beans:property name="lineAggregator">
            <beans:bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                <beans:property name="delimiter" value="|"/>
                <beans:property name="fieldExtractor">
                    <beans:bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                        <beans:property name="names" 
                        value="outcolomn1, outcolomn2, outcolomn3, outcolomn4"/>
                    </beans:bean>
                </beans:property>
            </beans:bean>
        </beans:property>
    </beans:bean>

    <step id="myPreProcessing1">
        <tasklet>
            <chunk reader="myInputFileReader" processor="myFileProcessor1" writer="fileItemWriter"
                commit-interval="10000"/>
        </tasklet>
    </step>

我必须添加其他(类似)步骤。我想使用相同的 readers 和作者,因为 reader 中的唯一变化将是一个新的 FieldSetMapper,而作者将是一个新的 BeanWrapperFieldExtractor。所以理想情况下,我想在父级指定一个 reader 和编写器,并希望通过覆盖新的映射器和提取器在所有步骤中引用它们。

使用Bean Definition Inheritance。创建一个抽象 bean 定义并让您的实际定义将其用作 parent.

<beans:bean id="parentInputFileReader" class="com.rbos.fm.risk.batch.spring.reader.InputFileReader" scope="step" abstract="true">
    <beans:property name="delegate">
        <beans:bean class="org.springframework.batch.item.file.FlatFileItemReader">
            <beans:property name="resource" ref="inputFileSystemResource" />
            <beans:property name="linesToSkip" value="1" />
        </beans:bean>
    </beans:property>
    <beans:property name="param1" value="#{jobParameters['param1']}"/>
    <beans:property name="param2" value="#{jobParameters['param2']}"/>
    <beans:property name="param3" value="#{jobParameters['param3']}"/>
</beans:bean>

<beans:bean id="parentLineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper" abstract="true">
    <beans:property name="lineTokenizer">
        <beans:bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
            <beans:property name="delimiter" value="|"/>
        </beans:bean>
    </beans:property>
</beans:bean>    

现在您有了父 Bean,您可以使用 parent 属性引用它们,并且只配置那些需要或需要修改默认值的属性。

<bean id="myInputFileReader" parent="parent">
    <beans:property name="lineMapper">
        <bean parent="parentLineMapper" >
            <beans:property name="fieldSetMapper">
                <beans:bean class="com.test.MyFieldMapper1" />
            </beans:property>
        </bean>
    </beans:property />
</bean>