You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch集成MongoDB配置解析失败:Bean定义冲突排查

问题

开发基于Spring Batch的功能,需求是读取Excel文件数据并写入MongoDB的students集合,计划通过API调用触发批处理任务。启动应用时始终报错:Failed to parse configuration class,配置代码如下:

package com.example.Study.Hall.Management.controller;

import com.example.Study.Hall.Management.model.Student;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MongoJobRepositoryFactoryBean;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.data.MongoItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.transaction.PlatformTransactionManager;

import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDate;

@Configuration
@EnableBatchProcessing
public class StudentBatchConfig {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Bean
    public JobRepository jobRepository(MongoTemplate mongoTemplate) throws Exception {
        MongoJobRepositoryFactoryBean factory = new MongoJobRepositoryFactoryBean();
        factory.setMongoOperations(mongoTemplate);
        return factory.getObject();  // Creates the JobRepository with MongoDB as the backend
    }

    @Bean
    public PlatformTransactionManager transactionManager(MongoTemplate mongoTemplate) {
        MongoDatabaseFactory mongoDatabaseFactory = mongoTemplate.getMongoDatabaseFactory();
        return new MongoTransactionManager(mongoDatabaseFactory);  // Provides transaction management for MongoDB
    }


    @Bean
    public Job importStudentJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
        return new JobBuilder("importStudentJob", jobRepository)
                .incrementer(new RunIdIncrementer()) // Optionally add a RunIdIncrementer for unique job instances
                .start(step1(jobRepository, transactionManager)) // Pass transaction manager to step1
                .build();
    }
    @Bean
    public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
        return new StepBuilder("step1", jobRepository)
                .<Student, Student>chunk(10, transactionManager) // Updated to include transaction manager
                .reader(excelReader())
                .processor(processor())
                .writer(writer())
                .build();
    }


    @Bean
    public ItemReader<Student> excelReader() {
        return new ItemReader<Student>() {
            private XSSFWorkbook workbook;
            private int currentRow = 0;

            @Override
            public Student read() throws Exception {
                if (workbook == null) {
                    workbook = new XSSFWorkbook(new FileInputStream("C://Users//moham//Desktop//students.xlsx"));
                }

                Row row = workbook.getSheetAt(0).getRow(currentRow++);
                if (row == null) {
                    workbook.close();
                    return null; // End of file
                }

                Student student = new Student();
                student.setName(row.getCell(0).getStringCellValue());
                student.setBloodGroup(row.getCell(1).getStringCellValue());
                student.setDateOfBirth(LocalDate.from(row.getCell(2).getLocalDateTimeCellValue()));
                student.setPhoneNumber(row.getCell(3).getStringCellValue());
                student.setExamPreparation(row.getCell(4).getStringCellValue());

                return student; // Return the populated Student object.
            }
        };
    }

    @Bean
    public ItemProcessor<Student, Student> processor() {
        return student -> {
            // You can add any processing logic here if needed.
            return student; // Return processed student object.
        };
    }

    @Bean
    public ItemWriter<Student> writer() {
        MongoItemWriter<Student> writer = new MongoItemWriter<>();
        writer.setTemplate(mongoTemplate);
        writer.setCollection("students");
        return writer;
    }
}

启动时的错误堆栈信息:

Error
 Failed to parse configuration class [com.example.Study.Hall.Management.StudyHallManagementApplication]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:185) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:418) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.4.1.jar:3.4.1]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.1.jar:3.4.1]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.1.jar:3.4.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.4.1.jar:3.4.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.4.1.jar:3.4.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.4.1.jar:3.4.1]
    at com.example.Study.Hall.Management.StudyHallManagementApplication.main(StudyHallManagementApplication.java:14) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.4.1.jar:3.4.1]
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'studentBatchConfig' for bean class [com.example.Study.Hall.Management.controller.StudentBatchConfig] conflicts with existing, non-compatible bean definition of same name and class [com.example.Study.Hall.Management.configurations.StudentBatchConfig]
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:361) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:288) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:128) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:332) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:267) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193) ~[spring-context-6.2.1.jar:6.2.1]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:171) ~[spring-context-6.2.1.jar:6.2.1

根因是存在两个同名同类型的Bean:com.example.Study.Hall.Management.controller.StudentBatchConfig和com.example.Study.Hall.Management.configurations.StudentBatchConfig,导致Bean定义冲突,进而引发配置类解析失败。


解决方法
  • 删除重复配置类:检查项目目录,直接删除其中一个StudentBatchConfig类。通常配置类应放在configurations包下,建议删除controller包下的重复类,避免逻辑冗余。
  • 指定唯一Bean名称:若必须保留两个类(不推荐),可通过@Configuration注解的value属性给其中一个类指定唯一Bean名,避免冲突:
    @Configuration("controllerStudentBatchConfig")
    @EnableBatchProcessing
    public class StudentBatchConfig {
        // 原有代码不变
    }
    
  • 调整组件扫描范围:修改启动类的@ComponentScan注解,排除其中一个包的配置类扫描:
    @SpringBootApplication
    @ComponentScan(excludeFilters = @ComponentScan.Filter(
            type = FilterType.ASSIGNABLE_TYPE,
            classes = com.example.Study.Hall.Management.controller.StudentBatchConfig.class
    ))
    public class StudyHallManagementApplication {
        public static void main(String[] args) {
            SpringApplication.run(StudyHallManagementApplication.class, args);
        }
    }
    

内容的提问来源于stack exchange,提问作者mohammed fahimullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:04:57