1. 什么是encoder?
1.1. Encoder负责两件事, 一是把事件转换为字节数组, 二是把字节数组写入输出流。在logback 0.9.19版之前没有encoder。在之前的版本里, 多数appender依靠layout来把事件转换成字符串并用java.io.Writer把字符串输出。在之前的版本里, 用户需要在FileAppender里嵌入一个PatternLayout。而从0.9.19版开始, FileAppender和其子类使用encoder, 不接受layout。
2. 为什么变了?
2.1. Layout只负责把事件转换为字符串。此外, 因为layout不能控制事件何时被写出, 所以不能成批地聚集事件。相比之下, encoder不但可以完全控制待写出的字节的格式, 而且可以控制字节何时及是否被写出。
2.2. 目前, PatternLayoutEncoder是唯一有用的encoder, 它基本上是封装了PatternLayout, 让PatternLayout负责大多数工作。因此, 似乎encoder并没有带来多少好东西, 反而只有不需要的复杂性。然而, 我们希望当新的、强大的encoder到来时, 这种印象会改变。
3. Encoder接口
3.1. Encoder负责把事件转换为字节数组并把字节数组写出到合适的输出流。因此, encoder可以完全控制在什么时候、把什么样的字节写入到由其拥有者appender维护的输出流。
3.2. Encoder接口
4. LayoutWrappingEncoder类
4.1. 在logback0.9.19版之前, appender依赖layout提供输出格式的灵活性。因为有大量现存代码是基于layout接口的, 所以我们需要想办法让encoder与layout实现互操作。 LayoutWrappingEncoder连接了encoder和layout, 它实现encoder接口, 并且包裹了一个layout, layout负责把事件转换成字符串。
4.2. 下面是LayoutWrappingEncoder类的代码片段, 阐述了如何把工作委托给layout实例。
4.3. encode方法首先让被包裹的layout把传入的事件转换成字符串, 再根据用户选择的字符集编码把字符串转换成字节。start方法自己写入其拥有者appender指定的输出流。
5. PatternLayoutEncoder类
5.1. 既然PatternLayout是最常用的layout, logback便提供了PatternLayoutEncoder, 它扩展了LayoutWrappingEncoder, 且仅使用PatternLayout。从logback 0.9.19版起, FileAppender或其子类在只要用到PattternLayout时, 都必须换成PatternLayoutEncoder。
5.2. PatternLayoutEncoder类