java.lang.IllegalStateException 当我在 spring 批次中将 FlatFileItemWriter 配置为带有 scpoe="step" 的流时
java.lang.IllegalStateException when i configure FlatFileItemWriter as stream with scpoe="step" in spring batch
我正在使用 spring 批处理并尝试将 FlatFileItemWriter
配置为流以将导致异常的所有记录记录到另一个平面文件中,我需要配置 scope="step"
这样我就可以使用占位符进行配置。
当我输入 scope="step"
时出现异常,但是当我删除它时,异常消失了。
这是作业的配置:
<batch:job id="helloWorldJob">
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="cvsFileItemReader" writer="cvsFileItemWriter"
processor="itemProcessor" commit-interval="10" skip-limit="9999">
<batch:skippable-exception-classes>
<batch:include class="java.lang.Exception" />
<batch:exclude class="java.io.FileNotFoundException" />
</batch:skippable-exception-classes>
<batch:streams>
<batch:stream ref="rejectFileItemWriter" />
</batch:streams>
</batch:chunk>
<batch:listeners>
<batch:listener ref="skipListner" />
</batch:listeners>
</batch:tasklet>
</batch:step>
</batch:job>
这里是 属性 writer 的 skip 侦听器的配置:
<bean id="skipListner" class="com.mykong.skipListner.RecordSkipListener">
<property name="writer" ref="rejectFileItemWriter"></property>
</bean>
这里是我给作者的配置:
<bean id="rejectFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="#{jobParameters['REJECTFILE']}" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator">
</bean>
</property>
</bean>
这是我得到的例外情况:
java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy2 implementing org.springframework.batch.item.file.ResourceAwareItemWriterItemStream,org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemWriter,org.springframework.batch.item.ItemStream,org.springframework.aop.scope.ScopedObject,java.io.Serializable,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [org.springframework.batch.item.file.FlatFileItemWriter] for property 'writer': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:450)
... 17 more
如果您在组件上设置 scope=step,spring 只会为该组件创建一个代理。
当 Spring 使用该代理时,它只会看到原始 class 的 "Interfaces",而不是 class 本身。
因此,如果它试图将此代理注入另一个组件,则定义的 属性 需要具有匹配的接口类型。它会拒绝将它注入某个地方,在那里你有 属性 和具体的 class 作为定义的类型。
查看您的异常,您会发现 FlatFileItemReader 的作用域代理实现了接口
org.springframework.batch.item.file.ResourceAwareItemWriterItemStream
org.springframework.beans.factory.InitializingBean
org.springframework.batch.item.ItemWriter
org.springframework.batch.item.ItemStream
org.springframework.aop.scope.ScopedObject java.io.Serializable
org.springframework.aop.framework.AopInfrastructureBean
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
似乎在某个 bean 中有一个名为 "writer" 的 属性,它被定义为应该注入此代理的 FlatFileItemReader。
但是,我在您提供的代码中没有看到这一点。
是否有另一个 Bean,您在其中尝试将 'rejectFileItemWriter' 注入到名为 "writer" 且类型为 "FlatFileItemReader" 的 属性 中?如果是,将此类型更改为接口 'ResourceAwareItemWriterItemStream' 可以解决问题。
根据您的代码,我假设您在处理器中使用此编写器来记录 "rejected" 文件。
我正在使用 spring 批处理并尝试将 FlatFileItemWriter
配置为流以将导致异常的所有记录记录到另一个平面文件中,我需要配置 scope="step"
这样我就可以使用占位符进行配置。
当我输入 scope="step"
时出现异常,但是当我删除它时,异常消失了。
这是作业的配置:
<batch:job id="helloWorldJob">
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="cvsFileItemReader" writer="cvsFileItemWriter"
processor="itemProcessor" commit-interval="10" skip-limit="9999">
<batch:skippable-exception-classes>
<batch:include class="java.lang.Exception" />
<batch:exclude class="java.io.FileNotFoundException" />
</batch:skippable-exception-classes>
<batch:streams>
<batch:stream ref="rejectFileItemWriter" />
</batch:streams>
</batch:chunk>
<batch:listeners>
<batch:listener ref="skipListner" />
</batch:listeners>
</batch:tasklet>
</batch:step>
</batch:job>
这里是 属性 writer 的 skip 侦听器的配置:
<bean id="skipListner" class="com.mykong.skipListner.RecordSkipListener">
<property name="writer" ref="rejectFileItemWriter"></property>
</bean>
这里是我给作者的配置:
<bean id="rejectFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="#{jobParameters['REJECTFILE']}" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator">
</bean>
</property>
</bean>
这是我得到的例外情况:
java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy2 implementing org.springframework.batch.item.file.ResourceAwareItemWriterItemStream,org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemWriter,org.springframework.batch.item.ItemStream,org.springframework.aop.scope.ScopedObject,java.io.Serializable,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [org.springframework.batch.item.file.FlatFileItemWriter] for property 'writer': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:450)
... 17 more
如果您在组件上设置 scope=step,spring 只会为该组件创建一个代理。 当 Spring 使用该代理时,它只会看到原始 class 的 "Interfaces",而不是 class 本身。 因此,如果它试图将此代理注入另一个组件,则定义的 属性 需要具有匹配的接口类型。它会拒绝将它注入某个地方,在那里你有 属性 和具体的 class 作为定义的类型。
查看您的异常,您会发现 FlatFileItemReader 的作用域代理实现了接口
org.springframework.batch.item.file.ResourceAwareItemWriterItemStream
org.springframework.beans.factory.InitializingBean
org.springframework.batch.item.ItemWriter
org.springframework.batch.item.ItemStream
org.springframework.aop.scope.ScopedObject java.io.Serializable
org.springframework.aop.framework.AopInfrastructureBean
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
似乎在某个 bean 中有一个名为 "writer" 的 属性,它被定义为应该注入此代理的 FlatFileItemReader。
但是,我在您提供的代码中没有看到这一点。
是否有另一个 Bean,您在其中尝试将 'rejectFileItemWriter' 注入到名为 "writer" 且类型为 "FlatFileItemReader" 的 属性 中?如果是,将此类型更改为接口 'ResourceAwareItemWriterItemStream' 可以解决问题。 根据您的代码,我假设您在处理器中使用此编写器来记录 "rejected" 文件。