没有类型为'的合格bean;org.springframework.batch.core.Job';可用:需要单个匹配bean,但找到2个:
基于输入参数,我有两个作业在single spring批处理应用程序中运行,它正在成功运行。但是当我运行我的测试用例时,我得到了下面的错误。我正在使用gradle构建我的应用程序 没有“org.springframework.batch.core.Job”类型的合格bean可用:需要单个匹配bean,但找到2:pureRedDataProcessingJob、pcsMasterProcessingJob 测试等级:没有类型为'的合格bean;org.springframework.batch.core.Job';可用:需要单个匹配bean,但找到2个:,spring,spring-boot,junit,spring-batch,Spring,Spring Boot,Junit,Spring Batch,基于输入参数,我有两个作业在single spring批处理应用程序中运行,它正在成功运行。但是当我运行我的测试用例时,我得到了下面的错误。我正在使用gradle构建我的应用程序 没有“org.springframework.batch.core.Job”类型的合格bean可用:需要单个匹配bean,但找到2:pureRedDataProcessingJob、pcsMasterProcessingJob 测试等级: import org.junit.FixMethodOrder; import
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;
}
}
/*
*/
导入java.util.HashMap;
导入java.util.Map;
导入java.util.StringTokenizer;
导入javax.sql.DataSource;
导入org.springframework.batch.core.Job;
导入org.springframework.batch.core.JobExecutionListener;
导入org.springframework.batch.core.Step;
导入org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
导入org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
导入org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
导入org.springframework.batch.core.launch.support.RunIdIncrementer;
导入org.springframework.batch.item.ItemWriter;
导入org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
导入org.springframework.batch.item.database.JdbcBatchItemWriter;
导入org.springframework.batch.item.file.FlatFileItemReader;
导入org.springframework.batch.item.file.MultiResourceItemReader;
导入org.springframework.batch.item.file.mapping.DefaultLineMapper;
导入org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.beans.factory.annotation.Qualifier;
导入org.springframework.beans.factory.annotation.Value;
导入org.springframework.boot.context.properties.ConfigurationProperties;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.core.io.Resource;
@配置
@配置属性
@启用批处理
公共类UidApplicationConfiguration{
@自动连线
私有数据源;
@自动连线
私人JobBuilderFactory JobBuilderFactory;
@自动连线
私人StepBuilderFactory StepBuilderFactory;
@豆子
PublicJobExecutionListener(){
返回新的JobCompletionNotificationListener();
}
@豆子
@限定符(“pureRedDataProcessingJob”)
公共作业pureRedDataProcessingJob(){
返回jobBuilderFactory.get(UidConstants.PURE\u RED\u作业)
.incrementer(新的RunIdIncrementer()).listener(listener())
.flow(pureRedStep()).end().build();
}
@豆子
公共步骤pureRedStep(){
返回stepBuilderFactory.get(“pureRedStep”).chunk(1)
.reader(multiResourcePureRedReader()).processor(pureRedProcessor()).writer(pureRedWriter()).faultTolerant()
.build();
}
@豆子
公共MultiResourceItemReader multiResourcePureRedReader()
{
MultiResourceItemReader resourceItemReader=新的MultiResourceItemReader();
setResources(getPureredFilePath());
setDelegate(pureRedReader());
返回resourceItemReader;
}
@SuppressWarnings({“rawtypes”,“unchecked”})
@豆子
公共FlatFileItemReader pureRedReader()
{
String[]namesArray={“circularType”、“rotoKey”、“xyCoordinate”、“xyCoordinate”、“xyCoordinate”、“adPrintVerNum”,
“adStartDttm”、“pageNum”、“itemWic”、“upc”、“headLineCopy”、“bodyCopy”、“xyCoordinate”、“pluCode”,
“vendorName”、“xyCoordinate”、“xyCoordinate”、“xyCoordinate”、“imageFileName”、“xyCoordinate”,
“报价”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”,
“数量”、“getFree”、“rewardSpend”、“rewardPoints”、“rewardQuantity”、“percentOff”、“offerLimit”,
“templateName”、“adPriceVerbiage”、“rewardVerbiage”、“fsiVerbiage”、“mirVerbiage”,
“ivcVerbiage”、“零售术语”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”,
“七个零件键”、“填充三个”、“大图像”、“XY坐标”、“XY坐标”、“XY坐标”、“XY坐标”,
“摘要”、“附加交易信息”、“免责声明”、“smallImage”};
pureRedBeanRapperFieldsSetMapper BeanRapper=新的pureRedBeanRapperFieldsSetMapper();
setTargetType(PureRedBean.class);
DefaultLineMapper linemapper=新的DefaultLineMapper();
DelimitedLineTokenizer标记器=新的DelimitedLineTokenizer(UidConstants.CSV_DELIMITER);
setNames(namesArray);
linemapper.setLineTokenizer(标记器);
BeanRapper.setDistanceLimit(0);
linemapper.setFieldSetMapper(BeanRapper);
//创建读卡器实例
FlatFileItemReader=新的FlatFileItemReader();
reader.setLineMapper(linemapper);
返回读取器;
}
@豆子
public ItemWriter pureRedWriter(){
JdbcBatchItemWriter writer=新的JdbcBatchItemWriter();
writer.setItemSqlParameterSourceProvider(新的BeanPropertyItemSqlParameterSourceProvider());
writer.setSql(pureredInsertQuery);
writer.setDataSource(mariaDb);
返回作者;
}
@豆子
公共PureRedProcessor PureRedProcessor(){
返回新的PureRedProcessor();
}
@豆子
@限定符(“pcsMasterProcessingJob”)
公共作业pcsMasterProcessingJob(){
返回jobBuilderFactory.get(UidConstants.PCS\u MASTER\u作业)
.incrementer(新的RunIdIncrementer()).listener(listener())
.flow(masterStep()).end().build();
}
@豆子
公共步骤masterStep(){
返回stepBuilderFactory.get(“masterStep”).chunk(1)
@Autowired
public void setJob(Job job) {
this.job = job;
}