Spring не создает экземпляр компонента с картой или списком в качестве свойства - PullRequest
0 голосов
/ 21 апреля 2020

Я реализую базовое c пакетное приложение с использованием Spring Boot и Spring Batch.

Для каждого файла, найденного во входном каталоге, создается один шаг благодаря MultiResourcePartitioner

<bean id="partitioner"
      class="org.springframework.batch.core.partition.support.MultiResourcePartitioner">
    <description>
        Create a step for each files found in the input directory
    </description>
    <property name="resources" value="#{resourceProvider.read()}"/>
</bean>

Каждый шаг состоит из ItemReader, ItemProcessor и ItemWriter. Моя проблема связана с ItemReader, и фактически каждый бин использует List / Map как свойство в конфигурации xml.

Мой ItemReader выглядит следующим образом:

<bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
    <description>
        * resource is set via step scoped late binding (see multiresourcereader)
        * strict mode - we expect input files
    </description>
    <property name="resource" value="#{stepExecutionContext['fileName']}"/>
    <property name="strict" value="true"/>
    <property name="lineMapper" ref="lineMapper"/>
</bean>

<bean id="lineMapper" class="input.CustomPatternMatchingLineMapper">
    <property name="fieldSetMappers">
        <map>
            <entry key="001*" value-ref="payloadFieldSetMapper"/>
            <entry key="000*" value-ref="headerFieldSetMapper"/>
            <entry key="999*" value-ref="footerFieldSetMapper"/>
        </map>
    </property>
    <property name="tokenizers">
        <map>
            <entry key="001*" value-ref="payloadTokenizer"/>
            <entry key="000*" value-ref="headerTokenizer"/>
            <entry key="999*" value-ref="footerTokenizer"/>
        </map>
    </property>
</bean>

<bean id="headerTokenizer" class="input.tokenizer.HeaderTokenizer"/>
<bean id="payloadTokenizer" class="input.tokenizer.PayloadTokenizer"/>
<bean id="footerTokenizer" class="input.tokenizer.FooterTokenizer"/>

<bean id="headerFieldSetMapper" class="input.fieldsetmapper.HeaderFieldSetMapper"/>
<bean id="payloadFieldSetMapper" class="input.fieldsetmapper.PayloadFieldSetMapper"/>
<bean id="footerFieldSetMapper" class="input.fieldsetmapper.FooterFieldSetMapper"/>

вот что я получаю в журнале при создании экземпляра бина

2020-04-21 10:22:32.491 DEBUG 6808 --- [           main] o.s.beans.TypeConverterDelegate          : Original ConversionService attempt failed - ignored since PropertyEditor based conversion eventually succeeded

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.util.LinkedHashMap<?, ?>] to type [@org.springframework.lang.Nullable java.util.Map<java.lang.Class<?>, java.lang.Class<java.beans.PropertyEditor>>] for value '{org.springframework.batch.item.file.transform.Range[]=org.springframework.batch.item.file.transform.RangeArrayPropertyEditor}'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [@org.springframework.lang.Nullable java.lang.Class<?>]
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:129) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1748) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1704) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:171) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at Lanceur.main(Lanceur.java:40) ~[classes/:na]
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [@org.springframework.lang.Nullable java.lang.Class<?>]
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.core.convert.support.MapToMapConverter.convertKey(MapToMapConverter.java:122) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.core.convert.support.MapToMapConverter.convert(MapToMapConverter.java:84) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    ... 23 common frames omitted

А вот где процесс висит бесконечно:

2020-04-21 10:22:36.261 DEBUG 6808 --- [cTaskExecutor-4] o.s.batch.core.scope.StepScope           : Creating object in scope=step, name=scopedTarget.itemReader

Для вашей информации, если я использую другой LineMapper, я не сталкиваюсь с этой проблемой.

Другая информация, поскольку я использую Spring Boot, мне пришлось переопределить определение StepScope, чтобы использовать свойство scope="step"

<bean id="stepScope" class="org.springframework.batch.core.scope.StepScope">
    <property name="autoProxy" value="true"/>
</bean>
spring.main.allow-bean-definition-overriding=true

EDIT
Вот пример строки, которую я должен отобразить, связанный с ней POJO и интерфейс, который он реализует:

001234577589NNNNNN                   FFF                        M
@Data
public class Payload implements Element {

    private String debLine;

    private String id;

    private String name;

    private String firstName;

    private String gender;

    private int numLine;
}
public interface Element {

    String getDebLine();

    int getNumLine();

    void setNumLine(int numLine);

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...