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

Spring Batch依赖循环问题分析与非拆分类修复方案

解决Spring Batch依赖循环问题

测试Spring Batch时遇到依赖循环问题,无法定位根源。希望在不拆分类的前提下修复该问题。

配置类代码

package org.id.demo.test.dao;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
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.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.transaction.PlatformTransactionManager;


@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {

    @Autowired
    private JobRepository jobRepository;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Autowired
    private ItemWriter<BankTransaction> bankTransactionItemWriter;
    @Autowired
    private ItemProcessor<BankTransaction, BankTransaction> bankTransactionItemProcessor;
    @Autowired
    private ItemReader<BankTransaction> flatFileItemReader;


    @Bean
    public Job bankJob() {
        TaskletStep step1 = new StepBuilder("step-load-data", jobRepository)
                .<BankTransaction, BankTransaction>chunk(100, platformTransactionManager)
                .reader(flatFileItemReader)
                .processor(bankTransactionItemProcessor)
                .writer(bankTransactionItemWriter)
                .build();

        return new JobBuilder("ETL-job", jobRepository)
                .start(step1)
                .build();
    }

    @Bean
    public FlatFileItemReader<BankTransaction> flatFileItemReader(@Value("${inputFile}") Resource inputFile) {
        FlatFileItemReader<BankTransaction> fileItemReader = new FlatFileItemReader<BankTransaction>();
        fileItemReader.setName("just a reader name");
        fileItemReader.setLinesToSkip(1);
        fileItemReader.setResource(inputFile);
        fileItemReader.setLineMapper(lineMapper());

        return fileItemReader;
    }

    @Bean
    public LineMapper<BankTransaction> lineMapper() {
        DefaultLineMapper<BankTransaction> lineMapper = new DefaultLineMapper<>();

        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setDelimiter(DelimitedLineTokenizer.DELIMITER_COMMA);
        lineTokenizer.setStrict(false);
        lineTokenizer.setNames("id", "accountID", "strTransactionDate", "transactionType", "amount");

        lineMapper.setLineTokenizer(lineTokenizer);

        BeanWrapperFieldSetMapper<BankTransaction> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(BankTransaction.class);
        lineMapper.setFieldSetMapper(fieldSetMapper);
        return lineMapper;
    }

}

报错信息

The dependencies of some of the beans in the application context form a cycle:

   jobRestController (field private org.springframework.batch.core.Job org.id.demo.test.dao.JobRestController.job)
┌─────┐
|  springBatchConfig (field private org.springframework.batch.item.ItemReader org.id.demo.test.dao.SpringBatchConfig.flatFileItemReader)
└─────┘

问题原因

Spring实例化SpringBatchConfig配置类时,需要先注入flatFileItemReader Bean,但flatFileItemReader本身由该配置类的@Bean方法创建。配置类的实例化依赖flatFileItemReader,而flatFileItemReader的创建又依赖配置类实例,形成循环依赖。

修复方案

移除配置类中对flatFileItemReader的@Autowired注入,直接在bankJob()方法中调用flatFileItemReader()方法获取Bean实例。Spring会对@Configuration类生成代理,调用@Bean方法时会返回容器中已存在的Bean(或触发创建),同时自动处理方法参数的依赖注入,避免循环依赖。

修改后的核心代码片段:

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {

    @Autowired
    private JobRepository jobRepository;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Autowired
    private ItemWriter<BankTransaction> bankTransactionItemWriter;
    @Autowired
    private ItemProcessor<BankTransaction, BankTransaction> bankTransactionItemProcessor;
    // 移除此处的@Autowired注入
    // @Autowired
    // private ItemReader<BankTransaction> flatFileItemReader;


    @Bean
    public Job bankJob() {
        TaskletStep step1 = new StepBuilder("step-load-data", jobRepository)
                .<BankTransaction, BankTransaction>chunk(100, platformTransactionManager)
                // 直接调用@Bean方法获取reader实例,Spring自动处理参数注入
                .reader(flatFileItemReader())
                .processor(bankTransactionItemProcessor)
                .writer(bankTransactionItemWriter)
                .build();

        return new JobBuilder("ETL-job", jobRepository)
                .start(step1)
                .build();
    }

    // 其余代码保持不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:26:00