Consumer接口不返回结果,适合执行消费动作,可通过装饰器模式或Lambda包装实现日志增强,推荐使用SLF4J等日志框架结合peek()在Stream中安全记录日志。

Consumer 接口本身不返回结果,适合执行“消费”动作(如打印、保存、校验),但默认不支持日志增强。要在消费数据时统一记录日志,核心思路是:用装饰器模式包装原始 Consumer,在执行前或后插入日志逻辑。
用 Lambda 包装实现日志增强
最轻量的方式是在创建 Consumer 时手动添加日志语句:
- 适用于简单场景,无需额外抽象
- 注意日志内容应包含关键上下文(如数据标识、操作类型)
- 示例:Consumer<String> loggedPrint = s -> {
System.out.println("【LOG】开始处理:" + s);
System.out.println("内容:" + s.toUpperCase());
System.out.println("【LOG】处理完成");
};
封装通用的日志 Consumer 工厂方法
为避免重复写日志模板,可定义静态工具方法生成带日志的 Consumer:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 支持传入操作描述,提升日志可读性
- 日志时机可灵活选择(执行前、后、或前后都记)
- 示例:public static <T> Consumer<T> withLogging(Consumer<T> delegate, String action) {
return t -> {
System.out.println("→ " + action + " 开始,输入:" + t);
delegate.accept(t);
System.out.println("← " + action + " 完成");
};
}
// 使用:Consumer<Integer> logger = withLogging(System.out::println, "打印数值");
结合 SLF4J 或 Log4j 实现生产级日志
实际项目中应使用标准日志框架,避免直接调用 System.out:
立即学习“Java免费学习笔记(深入)”;
- 用 Logger 替代 print,支持级别控制(INFO/DEBUG)、异步、格式化等
- 建议在日志中记录时间戳、线程名、输入对象 toString() 或关键字段
- 示例(SLF4J):private static final Logger log = LoggerFactory.getLogger(MyClass.class);
public static <T> Consumer<T> logBefore(Consumer<T> c, String op) {
return t -> {
log.info("【{}】接收输入: {}", op, t);
c.accept(t);
};
}
与 Stream pipeline 集成时的注意事项
在 map/filter/forEach 中使用带日志的 Consumer 时需留意:
- forEach 是终端操作,适合做日志;map 和 filter 中不要放副作用日志(违反函数式原则)
- 若需在中间步骤记录,优先用 peek() —— 它专为调试和日志设计
- 示例:list.stream()
.peek(item -> log.debug("预处理: {}", item))
.map(String::toUpperCase)
.forEach(withLogging(System.out::println, "输出"));

















