乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • 学习路径
  • 第1章 批处理概述与 Spring Batch 核心理念

    • Spring Batch 概述
    • Job-Instance-Execution 三层生命周期
    • 三层架构
    • Chunk 处理模型
    • Tasklet 处理模型
  • 第2章 Job与作业配置

    • Job 详解
    • Job 配置
    • JobLauncher 详解
    • JobParameters 详解
    • JobRepository 详解
  • 第3章 Step与执行模型

    • Step 详解
    • Step 配置
    • ExecutionContext 详解
    • ItemStream 与状态管理
    • StepScope 与 JobScope
  • 第4章 ItemReader数据读取

    • ItemReader 详解
    • FlatFileItemReader 详解
    • JdbcItemReader 详解
    • MultiResourceItemReader 详解
  • 第5章 ItemProcessor 数据处理

    • ItemProcessor 详解
  • 第6章 ItemWriter 数据写出

    • ItemWriter 详解
    • FlatFileItemWriter 详解
    • CompositeItemWriter 详解
    • JdbcBatchItemWriter 详解
  • 第7章 Chunk 处理与事务边界

    • Chunk 处理模型详解
    • 事务边界
  • 第8章 作业参数与启动

    • 命令行与 Web 启动
  • 第9章 监听器与拦截器

    • 监听器详解
  • 第10章 重启重试与跳过策略

    • 重启与重试
    • 跳过策略
  • 第11章 作业流与条件决策

    • 作业流与条件决策
  • 第12章 分区与并行处理

    • 分区详解
    • 并行 Step 与 Split
  • 第13章 与 Spring Boot 集成实践

    • Spring Boot 集成
  • 第15章 运维与监控

    • 大作业设计模式
    • 运维与监控

CompositeItemWriter 详解

本章定位:掌握 Spring Batch 中的多目标写入策略——CompositeItemWriter 和 ClassifierCompositeItemWriter 的完整用法。

定义与作用

CompositeItemWriter 将一个 Chunk 同时写入多个 Writer,实现"一次处理、多处落盘"。ClassifierCompositeItemWriter 根据数据特征将不同记录路由到不同 Writer。

飞翔科技运营部杨英的典型需求——同一批订单既要存数据库又要导出 CSV,小崔用 CompositeItemWriter 一行配置解决:

"CompositeItemWriter 就像在你家的水龙头上装了一个三通——水一开,厨房和洗衣机同时有水。"

核心原理

Composite vs Classifier

模式行为适用场景
CompositeItemWriter每个 Chunk 写入所有 Writer数据库 + 文件双写、主库 + 审计库
ClassifierCompositeItemWriter每条记录路由到一个 Writer按类型分文件、按状态分目标

完整示例

场景一:数据库 + 文件双写

@Bean
public CompositeItemWriter<StudentEntity> dualWriteWriter(
        JdbcBatchItemWriter<StudentEntity> dbWriter,
        FlatFileItemWriter<StudentEntity> fileWriter) {
    CompositeItemWriter<StudentEntity> writer = new CompositeItemWriter<>();
    writer.setDelegates(List.of(dbWriter, fileWriter));
    return writer;
}

场景二:按状态路由到不同文件

@Bean
public ClassifierCompositeItemWriter<Order> orderClassifierWriter() {
    ClassifierCompositeItemWriter<Order> writer = new ClassifierCompositeItemWriter<>();

    // 创建两个文件 Writer
    FlatFileItemWriter<Order> activeWriter = new FlatFileItemWriterBuilder<Order>()
            .name("activeWriter")
            .resource(new FileSystemResource("orders_active.csv"))
            .delimited().names("orderId", "customerName").build();

    FlatFileItemWriter<Order> cancelledWriter = new FlatFileItemWriterBuilder<Order>()
            .name("cancelledWriter")
            .resource(new FileSystemResource("orders_cancelled.csv"))
            .delimited().names("orderId", "customerName").build();

    writer.setClassifier(order -> {
        if ("CANCELLED".equals(order.getStatus())) {
            return cancelledWriter;
        }
        return activeWriter;
    });

    return writer;
}

运行结果:

Chunk 50 items: 42 ACTIVE + 8 CANCELLED
  → orders_active.csv: 追加 42 行
  → orders_cancelled.csv: 追加 8 行

易错场景与避坑

反例一:CompositeItemWriter 中一个 Writer 失败影响全部

// ❌ DB Writer 失败 → 整个 Chunk 回滚 → File Writer 也被回滚
// CompositeItemWriter 内所有 Writer 在同一个事务中

正确做法:如果某个 Writer 的失败不应影响其他 Writer,将该 Writer 移到单独的 Step 中,或配置为 non-transactional。

反例二:Classifier 忘记处理所有情况

// ❌ 未匹配的情况没有默认 Writer → NPE
writer.setClassifier(order -> {
    if ("ACTIVE".equals(order.getStatus())) return activeWriter;
    // CANCELLED 等其他状态 → 返回 null → NullPointerException
});

面试高频考点

Q1:CompositeItemWriter 的事务性如何保证?

所有委托的 Writer 共享 Step 的事务。任何一个 Writer 失败,整个 Chunk 回滚。如果需要独立的事务,必须将 Writer 拆分到不同的 Step。

Q2:ClassifierCompositeItemWriter 和 CompositeItemWriter 的区别?

CompositeItemWriter 将整个 Chunk 写入每个 Writer。ClassifierCompositeItemWriter 将每条记录路由到恰好一个 Writer。前者用于多目标复制,后者用于按规则分流。


上一章:JdbcBatchItemWriter 详解下一章:Chunk 处理模型详解

上一页
FlatFileItemWriter 详解
下一页
JdbcBatchItemWriter 详解