Spring 3.2 - 如何将 XML 中配置的 FlatFileItemWriter 注入 java 类中的参数化属性

Posted

技术标签:

【中文标题】Spring 3.2 - 如何将 XML 中配置的 FlatFileItemWriter 注入 java 类中的参数化属性【英文标题】:Spring 3.2 - how to inject FlatFileItemWriter configured in XML to parameterized property in java class 【发布时间】:2015-06-23 13:33:14 【问题描述】:

我们有一个当前的应用程序,它使用在 XML 中配置的 FlatFileItemWriter 来生成一个固定长度的记录文件(“FileItemWriter”)。我们想添加第二个 ItemWriter 作为 Java 类,它将处理相同的块以更新 DB 中的 hstory 表(“HistoryItemWriter”)。已实现第三个 Java ItemWriter(“DispatcherItemWriter”)依次调用这些家伙,传递块。

问题是将 XML 中配置的 FlatFileItemWriter 的引用注入到 DispatcherItemWriter 类中的 FlatFileItemWriter 属性。日志显示正在检索的 bean 引用,但随后会引发 ConversionNotSupportedexception(日志 sn-p 下面)。

DispatcherItemWriter Java 类中的 FlatFileItemWriter 属性被定义为参数化,但无法在 XML 中类似地表示参数化,尽管至少有一篇文章表明这​​在 4.0 中是可能的(目前还不是一个选项)。

我尝试了各种使用@Autowired、@Resource 和无注释的方法,以及定义带有和不带参数化的属性,并且还尝试了 bean 上的 'p:fileItemWriter-ref="fileItemWriter"'和 bean 中的 'property name="fileItemWriter" ref="fileItemWriter"'。 Spring 发现 bean 没问题,但总是以“找不到匹配的编辑器或转换策略”而失败。

有人在 3.2 中完成了这个吗?

这里是fileItemWriter的配置:

<bean id="fileItemWriter" 
    class="org.springframework.batch.item.file.FlatFileItemWriter" 
    scope="step">
    <property  name="resource" value="file:$strRunFileName" /> 
    <property  name="lineAggregator">
    . . . etc.
    </property >
</bean>

这里是 dispatcherItemWriter bean 配置:

<bean id="dispatcherItemWriter" 
    class="com.xyz.DispatcherItemWriter" 
    scope="step">
    <property name="fileItemWriter" ref="fileItemWriter" />
</bean>

historyItemWriter 配置如下:

<bean id="historyItemWriter" 
    class="com.xyz.HistoryItemWriter" 
    scope="step" 
    p:dataSource-ref="dataSource" />    

这是 HistoryItemWriter 类中的变量声明:

    @Component
    public class RejectItemWriter implements ItemWriter<RejectResult> 
        // fileItemWriter is defined in module-context.xml
        @SuppressWarnings("rawtypes")
        // @Autowired
        @Resource(name="fileItemWriter")
        // private FlatFileItemWriter <Result> fileItemWriter;
        private FlatFileItemWriter fileItemWriter;

这是 Tasklet:

<batch:tasklet>
    <batch:chunk 
        reader="itemReader" 
        processor="ItemProcessor" 
        writer="dispatcherItemWriter" 
        commit-interval="1000" />
</batch:tasklet>

这里是日志的相关部分:

16:31:48.342 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - 
Returning cached instance of singleton bean 'fileItemWriter'
16:31:48.342 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - 
Failed to convert bean 'fileItemWriter' 
to required type 
[org.springframework.batch.item.file.FlatFileItemWriter]
org.springframework.beans.ConversionNotSupportedException: 
Failed to convert value of type 'sun.proxy.$Proxy10 implementing 
org.springframework.batch.item.file.ResourceAwareItemWriterItemStream,
org.springframework.beans.factory.InitializingBean,
org.springframework.batch.item.ItemWriter,
org.springframework.batch.item.ItemStream,
java.io.Serializable,
org.springframework.aop.scope.ScopedObject,
org.springframework.aop.framework.AopInfrastructureBean,
org.springframework.aop.SpringProxy,
org.springframework.aop.framework.Advised' 
to required type 
'org.springframework.batch.item.file.FlatFileItemWriter'; 
nested exception is java.lang.IllegalStateException: 
Cannot convert value of type [sun.proxy.$Proxy10 implementing 
org.springframework.batch.item.file.ResourceAwareItemWriterItemStream,
org.springframework.beans.factory.InitializingBean,
org.springframework.batch.item.ItemWriter,
org.springframework.batch.item.ItemStream,
java.io.Serializable,
org.springframework.aop.scope.ScopedObject,
org.springframework.aop.framework.AopInfrastructureBean,
org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] 
to required type [org.springframework.batch.item.file.FlatFileItemWriter]: 
no matching editors or conversion strategy found

注意org.springframework.batch.item.ItemWriter在实现的接口列表中,所有的接口和实现类都是参数化的。

【问题讨论】:

【参考方案1】:

无需创建DispatchItemWriter,spring batch 已经实现了你要找的用例,使用CompositeItemWriter。可以找例子here

【讨论】:

谢谢!这正是我所需要的。不知道为什么我没有在文档中找到它。 我用 ComositeItemWriter 替换了我的 Java 调度程序。这解决了 bean 创建问题,但现在日志显示“FlatFileItemWriter - 写入包含 0 个项目的平面文件。”。这意味着 FlatFileItemWriter 的 write() 方法现在被传递一个空块。我错过了什么吗?这是 bean 配置: (等等) 请用整个配置文件更新问题(问题也可能出于其他原因),否则如果只有一个简单的文件项编写器正在工作,请先尝试。一旦 fileitemwrtier 工作,您就可以更新为复合项目编写器 嗨@Karthik,当我的java'dispatcher'调用FlatFileItemWriter并处理了1000个项目的第一块时,它正在工作;然后在注入对第二个写入器的引用时出现 bean 配置问题,该写入器会将记录插入历史表。我将在 cmets 中发布其余配置以供跟进。 Tasklet,为 CompositeItemWriter 修改:&lt;batch:tasklet&gt; &lt;batch:chunk reader="itemReader" processor="rejectItemProcessor" writer="compositeItemWriter" commit-interval="1000" /&gt; &lt;/batch:tasklet&gt;

以上是关于Spring 3.2 - 如何将 XML 中配置的 FlatFileItemWriter 注入 java 类中的参数化属性的主要内容,如果未能解决你的问题,请参考以下文章

如何让是spring启动时加载一个类。这里类实现了读取xml配置数据到内存中(不是属性文件)

SSM的整合

如何在 XML 配置文件中使用 Spring Boot 自动配置的 bean?

如何在没有 persistence.xml 的情况下配置 Spring?

Spring - 将Java Config和Xml结合起来引用遗留XML中定义的bean

如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java config