介绍
@DerivedField 用于从已解码的原始协议字段中衍生出业务视图,而无需改动原有的编解码字段。
典型的应用场景:
- 将
long类型的位段(如状态字)自动解析为Set<Enum>,而非手动编写位运算 - 将原始数值映射为可读的业务描述(如
0 → "offline",1 → "online") - 编码时将业务视图逆向回写为原始协议的字段值
@DerivedField 用于从已解码的原始协议字段中衍生出业务视图,而无需改动原有的编解码字段。
典型的应用场景:
long 类型的位段(如状态字)自动解析为 Set<Enum>,而非手动编写位运算0 → "offline",1 → "online")传送门
当前示例源码位于 quick-start/custom-annotation-server
传送门
当前示例源码位于 quick-start/custom-annotation-server
在 之前的版本中,无论是 内置注解 还是 自定义注解,表达式 都是通过 SpEL 来实现的。
从 开始,xtream-codec 新增了 @Expression 注解。支持三种表达式:
协议是会进化的。版本升级时,往往只是部分字段发生变化:
u8,新版本变成了 u16若为每个版本维护一套独立的 Entity 类,代码将迅速膨胀,版本之间的差异淹没在重复的 boilerplate 中。
@XtreamField 的 version 属性便是为此而生——在 同一 Entity 类 中,通过 同一字段 上的多个注解声明,精确控制每个版本下该字段的编解码行为。
只需要给 EntityCodec 的 encode 或 decode 方法传入一个 CodecTracker 实例即可追踪每个字段的编解码详情。
警告
CodecTracker 的设计目的仅仅是用来调试。 会对编解码性能产生 严重 影响。
提示
这里介绍的是 io.github.hylexus.xtream.codec.core.EntityCodec
EntityCodec 用来支持基于注解的编解码。这里的注解指的是前面提到的:
@XtreamField()@Preset.RustStyle.xxx()@Preset.JtStyle.xxx()这里说的 参数解析器 指的是 XtreamHandlerMethodArgumentResolver。
名字比较长,但从命名中可以看出来它本质上是一个 方法参数的解析器。
下面代码段中 processMessage0200V2019 方法的所有参数都是通过 XtreamHandlerMethodArgumentResolver 解析出来的:
@Component
@Jt808RequestHandler
public class DemoJt808RequestHandler {
@Jt808RequestHandlerMapping(messageIds = 0x0200, versions = Jt808ProtocolVersion.VERSION_2019)
@Jt808ResponseBody(messageId = 0x8001, maxPackageSize = 1000)
public Mono<ServerCommonReplyMessage> processMessage0200V2019(
XtreamExchange exchange,
XtreamSession xtreamSession,
XtreamRequest xtreamRequest,
Jt808Request jt808Request,
DefaultXtreamRequest defaultXtreamRequest,
XtreamResponse xtreamResponse,
DefaultXtreamResponse defaultXtreamResponse,
Jt808RequestEntity<BuiltinMessage0200> requestEntity,
@Jt808RequestBody DemoLocationMsg01 msg01,
@Jt808RequestBody DemoLocationMsg02 msg02,
@Jt808RequestBody ByteBuf buf01,
@Jt808RequestBody ByteBuf buf02,
@Jt808RequestBody(bufferAsSlice = false) ByteBuf buf03,
@Jt808RequestBody(bufferAsSlice = false) ByteBuf buf04) {
log.info("v2019-0x0200: {}", msg01);
assertNotSame(buf01, buf02);
assertNotSame(buf01, buf03);
assertSame(buf03, buf04);
assertSame(exchange.request(), xtreamRequest);
assertSame(exchange.request(), jt808Request);
assertSame(exchange.request(), defaultXtreamRequest);
assertSame(exchange.response(), xtreamResponse);
assertSame(exchange.response(), defaultXtreamResponse);
final ServerCommonReplyMessage responseBody = ServerCommonReplyMessage.success(jt808Request);
return Mono.just(responseBody);
}
}