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

Spring Batch启动时读取CSV存入HashMap的实现咨询

Spring Batch 读取CSV到全局可用HashMap的实现方案

核心结论

Spring Batch没有专门内置的ItemWriter用于写入内存HashMap,但你可以自定义实现ItemWriter<T>接口来完成这个需求,同时通过Spring Bean将HashMap配置为全局可用。


实现步骤与代码示例

1. 定义CSV对应的实体类

先创建与CSV字段匹配的POJO:

public class User {
    private String id;
    private String name;

    // 生成getter、setter方法
    // 可选:生成toString()方便调试
}

2. 配置全局可用的HashMap Bean

用ConcurrentHashMap保证线程安全(Spring Batch可能多线程处理任务),并注册为Spring Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Configuration
public class GlobalBeanConfig {
    @Bean
    public Map<String, User> userGlobalMap() {
        return new ConcurrentHashMap<>();
    }
}

3. 自定义ItemWriter写入HashMap

实现ItemWriter<User>接口,注入全局HashMap,批量写入数据:

import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;

@Component
public class HashMapItemWriter implements ItemWriter<User> {

    private final Map<String, User> userGlobalMap;

    // 构造方法注入全局HashMap
    @Autowired
    public HashMapItemWriter(Map<String, User> userGlobalMap) {
        this.userGlobalMap = userGlobalMap;
    }

    @Override
    public void write(List<? extends User> items) throws Exception {
        // 批量将数据存入HashMap,这里用id作为key
        items.forEach(user -> userGlobalMap.put(user.getId(), user));
    }
}

4. 配置Spring Batch作业

组装Reader(读取CSV)、Writer(写入HashMap),构建完整作业:

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.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.file.FlatFileItemReader;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
@EnableBatchProcessing
public class BatchJobConfig {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private final HashMapItemWriter hashMapItemWriter;

    public BatchJobConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, HashMapItemWriter hashMapItemWriter) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
        this.hashMapItemWriter = hashMapItemWriter;
    }

    // 配置CSV读取器
    @Bean
    public FlatFileItemReader<User> csvUserReader() {
        FlatFileItemReader<User> reader = new FlatFileItemReader<>();
        // 指定CSV文件路径(这里放在resources目录下)
        reader.setResource(new ClassPathResource("users.csv"));
        // 配置行映射:分割字段并映射到User类
        reader.setLineMapper(new DefaultLineMapper<User>() {{
            setLineTokenizer(new DelimitedLineTokenizer() {{
                // CSV的列名,要和User类的属性名对应
                setNames("id", "name");
            }});
            setFieldSetMapper(new BeanWrapperFieldSetMapper<User>() {{
                setTargetType(User.class);
            }});
        }});
        return reader;
    }

    // 配置处理步骤
    @Bean
    public Step csvToHashMapStep() {
        return stepBuilderFactory.get("csvToHashMapStep")
                .<User, User>chunk(100) // 按100条为一批处理,可根据文件大小调整
                .reader(csvUserReader())
                .writer(hashMapItemWriter)
                .build();
    }

    // 配置完整作业
    @Bean
    public Job csvToHashMapJob() {
        return jobBuilderFactory.get("csvToHashMapJob")
                .start(csvToHashMapStep())
                .build();
    }
}

5. 让作业在应用启动时自动执行

Spring Boot默认会自动执行所有注册的Batch Job(通过spring.batch.job.enabled=true,默认开启)。如果有多个Job,可在application.properties中指定要执行的Job:

spring.batch.job.names=csvToHashMapJob

全局使用HashMap

在其他Spring组件中,直接通过@Autowired注入全局HashMap即可使用:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;

@Service
public class UserService {
    private final Map<String, User> userGlobalMap;

    @Autowired
    public UserService(Map<String, User> userGlobalMap) {
        this.userGlobalMap = userGlobalMap;
    }

    public User getUserById(String id) {
        return userGlobalMap.get(id);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:07:56