从 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>
下面是我的步骤配置 -
<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>