使用spring注释使用defaultLineMapper创建自定义ItemReader

时间:2014-07-08 06:44:58

标签: spring annotations spring-batch

我正在尝试在spring-batch中创建基于注释的ItemReader。我能够在我的xml中创建所需的ItemReader,但基于注释完全没有工作,给出以下错误:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'runScheduler': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.batch.core.Job com.techavalanche.batch.RunScheduler.job; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportJob': Cannot create inner bean '(inner bean)#3f9bb1' of type [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean] while setting bean property 'flow'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3f9bb1': Cannot create inner bean '(inner bean)#17e6f05' of type [org.springframework.batch.core.job.flow.support.StateTransition] while setting bean property 'stateTransitions' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#17e6f05': Cannot create inner bean '(inner bean)#66da50' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#66da50': Cannot resolve reference to bean 'step1' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'step1': Cannot resolve reference to bean 'customItemReader' while setting bean property 'itemReader'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customItemReader': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.springframework.batch.item.file.FlatFileItemReader com.techavalanche.reader.CustomReader.itemReader; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getFlatFileItemReader' defined in class path resource [com/techavalanche/reader/CustomReader.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: LineMapper is required

由以下原因引起:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.batch.core.Job com.techavalanche.batch.RunScheduler.job; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportJob': Cannot create inner bean '(inner bean)#3f9bb1' of type [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean] while setting bean property 'flow'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3f9bb1': Cannot create inner bean '(inner bean)#17e6f05' of type [org.springframework.batch.core.job.flow.support.StateTransition] while setting bean property 'stateTransitions' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#17e6f05': Cannot create inner bean '(inner bean)#66da50' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#66da50': Cannot resolve reference to bean 'step1' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'step1': Cannot resolve reference to bean 'customItemReader' while setting bean property 'itemReader'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customItemReader': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.springframework.batch.item.file.FlatFileItemReader com.techavalanche.reader.CustomReader.itemReader; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getFlatFileItemReader' defined in class path resource [com/techavalanche/reader/CustomReader.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: LineMapper is required

我的CustomReader是

package com.techavalanche.reader;

@Component("customReader")
public class CustomReader implements ItemReader<Report> {


    @Autowired
    public FlatFileItemReader<Report> itemReader;

    @Bean 
    public FlatFileItemReader getFlatFileItemReader(){

        return new FlatFileItemReader();
    }


    @Bean
    public DefaultLineMapper getDefaultLineMapper(){

        return new DefaultLineMapper();
    }

    @Autowired
    public DefaultLineMapper<Report> lineMapper;



    @Bean
    public FixedLengthTokenizer getLinetokenizer(){     
        return new FixedLengthTokenizer();
    }
    @Autowired
    public FixedLengthTokenizer linetokenizer;

    @Bean
    public BeanWrapperFieldSetMapper getBeanWrapperFieldSetMapper() {

        return new BeanWrapperFieldSetMapper();
    }


    @Autowired  
    public BeanWrapperFieldSetMapper<Report> fieldSetMapper;

    public Resource res=new FileSystemResource("D:\\testresource\\report.csv");



    String[] names= {"date","impressions","clicks","earning"};


    @Override
    public Report read() throws Exception, UnexpectedInputException, ParseException,
    NonTransientResourceException {


        for(String name:names){         
            System.out.println(name);
        }

        linetokenizer.setNames(new String[] {"date","impressions","clicks","earning"}); 

        Range range1=new Range(1,12);
        Range range2=new Range(13,15);
        Range range3=new Range(16,20);
        Range range4=new Range(21,28);
        Range[] ranges={range1,range2,range3,range4};

        linetokenizer.setColumns(ranges);
        lineMapper.setLineTokenizer(linetokenizer);     


        fieldSetMapper.setPrototypeBeanName("report");      
        lineMapper.setFieldSetMapper(fieldSetMapper);

        itemReader.setResource(res);
        itemReader.setLineMapper(lineMapper);   


        itemReader.open(new ExecutionContext());
        Report report= itemReader.read();       

        return report;

    }
}

我的Xml配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/batch
    http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.2.xsd
    ">
     <context:component-scan base-package="com.techavalanche" />
    <bean id="jobRepository"
        class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager" />
    </bean>
    <bean id="transactionManager"
        class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

    <bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
    </bean>

    <bean id="report" class="com.techavalanche.batch.Report" scope="prototype" />

    <bean id="customWriter" class="com.techavalanche.writer.CustomWriter" />


    <batch:job id="reportJob">
        <batch:step id="step1">
            <batch:tasklet>
                <batch:chunk reader="customItemReader" writer="customWriter"
                    commit-interval="2">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>

    <bean id="multiResourceReader"
        class=" org.springframework.batch.item.file.MultiResourceItemReader">
        <property name="resources" value="file:D:\testresource\report.csv" />
        <property name="delegate" ref="cvsFileItemReader" />
    </bean>

    <bean id="customItemReader" class="com.techavalanche.reader.CustomReader" />
    <bean id="cvsFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
        <!-- Read a csv file -->
        <!-- <property name="resource" ref="resource" /> -->

        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <!-- split it -->
                <property name="lineTokenizer">
                    <bean id="fixedLengthLineTokenizer"
                        class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
                        <property name="names" value="date,impressions,clicks,earning" />
                        <property name="columns" value="1-12,13-15,16-20,21-28" />
                    </bean>
                </property>
                <property name="fieldSetMapper">
                    <!-- return back to reader, rather than a mapped object. -->
                    <!-- <bean class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" 
                        /> -->
                    <!-- map to an object -->
                    <bean
                        class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                        <property name="prototypeBeanName" value="report" />
                    </bean>
                </property>

            </bean>
        </property>

    </bean>
</beans>

0 个答案:

没有答案