spring - 没有 'org.springframework.batch.core.Job' 类型的合格 bean 可用 : expected single matching bean but found 2:

标签 spring spring-boot junit spring-batch

我有 2 个作业根据输入参数在单个 spring 批处理应用程序中运行,并且运行成功。但是当我运行我的测试用例时,我收到以下错误。我正在使用 gradle 来构建我的应用程序。

没有可用的“org.springframework.batch.core.Job”类型的合格 bean:预期单个匹配 bean,但发现 2:pureRedDataProcessingJob,pcsMasterProcessingJob

测试类:

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**

 * 
 * @author 
 *
 */
@ContextConfiguration(classes = {UidBatchApplication.class, JobLauncherTestUtils.class}, 
initializers = ConfigFileApplicationContextInitializer.class)
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(locations = {"classpath:application-test.properties"})
@Configuration
@ActiveProfiles("test")
@Profile("test")
@TestConfiguration
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)

@EnableAutoConfiguration

public class UidBatchApplicationTest {


    @Autowired
    public JobLauncherTestUtils jobLauncherTestUtils;


    @Test
    public void launchJob() throws Exception {
        JobParameters params = new JobParametersBuilder().addString("jobName", "pcsMasterProcessingJob").toJobParameters();
        jobLauncherTestUtils.launchJob(params);
    }

}

主类配置:
/*

 */



import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;




@Configuration
@ConfigurationProperties
@EnableBatchProcessing

public class UidApplicationConfiguration{

    @Autowired
    private DataSource mariaDb;

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public JobExecutionListener listener() {
        return new JobCompletionNotificationListener();
    }

    @Bean
    @Qualifier("pureRedDataProcessingJob")
    public Job pureRedDataProcessingJob() {
        return jobBuilderFactory.get(UidConstants.PURE_RED_JOB)
                .incrementer(new RunIdIncrementer()).listener(listener())
                .flow(pureRedStep()).end().build();
    }

    @Bean
    public Step pureRedStep() {
        return stepBuilderFactory.get("pureRedStep").<PureRedBean, PureRedBean> chunk(1)
                .reader(multiResourcePureRedReader()).processor(pureRedProcessor()).writer(pureRedWriter()).faultTolerant()
                .build();
    }

    @Bean
    public MultiResourceItemReader<PureRedBean> multiResourcePureRedReader()
    {
        MultiResourceItemReader<PureRedBean> resourceItemReader = new MultiResourceItemReader<>();
        resourceItemReader.setResources(getPureredFilePath());
        resourceItemReader.setDelegate(pureRedReader());
        return resourceItemReader;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FlatFileItemReader<PureRedBean> pureRedReader()
    {
        String[] namesArray = {"circularType","rotoKey","xyCoordinate","xyCoordinate","xyCoordinate","adPrintVerNum",
                "adStartDttm","pageNum","itemWic","upc","headLineCopy","bodyCopy","xyCoordinate","pluCode",
                "vendorName","xyCoordinate","xyCoordinate","xyCoordinate","imageFileName","xyCoordinate",
                "offerPrice","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate",
                "quantity","getFree","rewardSpend","rewardPoints","rewardQuantity","percentOff","offerLimit",
                "templateName","adPriceVerbiage","rewardVerbiage","fsiVerbiage","mirVerbiage",
                "ivcVerbiage","retailVerbiage","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate",
                "sevenPartKey","fillerThree","largeImage","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate",
                "summary","additionalDealInfo","disclaimer","smallImage"};
        PureredBeanWrapperFieldSetMapper beanWrapper = new PureredBeanWrapperFieldSetMapper();
        beanWrapper.setTargetType(PureRedBean.class);
        DefaultLineMapper linemapper = new DefaultLineMapper();
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(UidConstants.CSV_DELIMITER);
        tokenizer.setNames(namesArray);
        linemapper.setLineTokenizer(tokenizer );
        beanWrapper.setDistanceLimit(0);
        linemapper.setFieldSetMapper(beanWrapper);

        //Create reader instance
        FlatFileItemReader<PureRedBean> reader = new FlatFileItemReader<>();         
        reader.setLineMapper(linemapper);
        return reader;
    }

    @Bean
    public ItemWriter<PureRedBean> pureRedWriter() {        
        JdbcBatchItemWriter<PureRedBean> writer = new JdbcBatchItemWriter<>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<PureRedBean>());
        writer.setSql(pureredInsertQuery);      
        writer.setDataSource(mariaDb);
        return writer;
    }

    @Bean
    public PureRedProcessor pureRedProcessor() {
        return new PureRedProcessor();
    }

    @Bean
    @Qualifier("pcsMasterProcessingJob")
    public Job pcsMasterProcessingJob() {
        return jobBuilderFactory.get(UidConstants.PCS_MASTER_JOB)
                .incrementer(new RunIdIncrementer()).listener(listener())
                .flow(masterStep()).end().build();
    }

    @Bean
    public Step masterStep() {
        return stepBuilderFactory.get("masterStep").<UniqueIdMasterBean, UniqueIdMasterBean> chunk(1)
                .reader(multiResourceItemReader()).processor(masterProcessor()).writer(writer()).faultTolerant()
                .build();
    }

    @Bean
    public MultiResourceItemReader<UniqueIdMasterBean> multiResourceItemReader()
    {
        MultiResourceItemReader<UniqueIdMasterBean> resourceItemReader = new MultiResourceItemReader<>();
        resourceItemReader.setResources(getFilePath());
        resourceItemReader.setDelegate(reader());
        return resourceItemReader;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FlatFileItemReader<UniqueIdMasterBean> reader()
    {
        String[] namesArray = {"uniqueId","spotSeqNum","adTypeCd","adMarketCd","adStartDttm","adExpiryDttm",
                "adEventType","adSeqNum","adVerCd","adVerSeqNum","adPrintVerNum","adLoyaltyOfferCd","adItemCouponNum",
                "adItemLayoutPosNum","adItemPageNum","adItemRetailMultiple","adItemRetailPrice","adItemSingleUnitPrice",
                "adItemAltPriceMult","adItemAltPrice","adItemAmtOff","adItemPercentOff","adPageTypeCd","minOrderValue",
                "rewardType","offerValue","loyaltyPoints","targetedFlag","","categoryLevelTwo","adFillerOne",
                "adFillerTwo","adFillerThree","statusFlagOne","statusFlagTwo"};
        BeanWrapperFieldSetMapperCustom beanWrapper = new BeanWrapperFieldSetMapperCustom();
        beanWrapper.setTargetType(UniqueIdMasterBean.class);
        DefaultLineMapper linemapper = new DefaultLineMapper();
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(UidConstants.CSV_DELIMITER);
        tokenizer.setNames(namesArray);
        linemapper.setLineTokenizer(tokenizer );
        linemapper.setFieldSetMapper(beanWrapper);

        //Create reader instance
        FlatFileItemReader<UniqueIdMasterBean> reader = new FlatFileItemReader<>();      
        reader.setLineMapper(linemapper);
        return reader;
    }

    @Bean
    public ItemWriter<UniqueIdMasterBean> writer() {        
        JdbcBatchItemWriter<UniqueIdMasterBean> writer = new JdbcBatchItemWriter<>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<UniqueIdMasterBean>());
        writer.setSql(insertQuery);     
        writer.setDataSource(mariaDb);
        return writer;
    }

    @Bean
    public MasterProcessor masterProcessor() {
        return new MasterProcessor();
    }

    @Value("${master.filePath}")
    private Resource[] filePath;
    @Value("${master.insertQuery}")
    private String insertQuery;
    @Value("${purered.filePath}")
    private Resource[] pureredFilePath;
    @Value("${purered.insertQuery}")
    private String pureredInsertQuery;
    @Value("${categoryList}")
    private String categoryList;
    private Map<String,String> categoryMap;

    public Resource[] getPureredFilePath() {
        return pureredFilePath;
    }

    public Resource[] getFilePath() {
        return filePath;
    }

    public void setCategoryList(String categoryList) {
        this.categoryList = categoryList;
    }

    /**
     * @return the clientTagsMap
     */
    public Map<String, String> getCategoryMap() {
        if(null == categoryMap){
            categoryMap = new HashMap<>();
            int count = 0;
            String current = "";
            String value = null;
            String key = null ;
            StringTokenizer tok = new StringTokenizer(categoryList, ",=");
            while (tok.hasMoreTokens()) {
                current = tok.nextToken();
                // the first token in the pair is the key
                if (count%(PCSConstants.KEY_LENGTH)==1){
                    value =  current;
                    categoryMap.put(key, value);
                }else{
                    // the second is the value
                    key = current;
                }
                count++;
            }
        }
        return categoryMap;
    }
}

有人可以帮我吗。

最佳答案

您可能需要手动配置 JobLauncherTestUtils .
这看起来类似于这里的线程
Spring Batch JUnit test for multiple jobs

查看JobLauncherTestUtils的代码,这是导致问题的原因。

@Autowired
    public void setJob(Job job) {
        this.job = job;
    }

关于spring - 没有 'org.springframework.batch.core.Job' 类型的合格 bean 可用 : expected single matching bean but found 2:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53150048/

相关文章:

java - Spring:取消一个@Scheduled注解的任务

mysql - Spring @Transactional 死锁

java - Bean 属性不可读或具有无效的 getter 方法

java - NullPointerException 在 org.springframework.roo.project.packaging.WarPackaging.createOtherArtifacts(WarPackaging.java :41)

java - JUnit 测试的默认工作目录 - 我们如何在 Eclipse 中一致地定义它?

java - 如何摆脱自动安装新表

spring-boot - 多个微服务的通用应用程序属性文件

spring - liquibase-hibernate5 不适用于 liquibase-maven-plugin

java - 使用@Rule 删除样板测试代码

java - 在 JUNIT 测试中未创建 Hibernate 事务