io.netty.util.internal.TypeParameterMatcher
定义: 类型参数匹配器
功能: 用于判断 SimpleChannelInboundHandler<?> 中传入参数是否是该handler要处理的 message
io.netty.channel.SimpleChannelInboundHandler
public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter {
private final TypeParameterMatcher matcher;
private final boolean autoRelease;
protected SimpleChannelInboundHandler() {
this(true);
}
protected SimpleChannelInboundHandler(boolean autoRelease) {
this.matcher = TypeParameterMatcher.find(this, SimpleChannelInboundHandler.class, "I");
this.autoRelease = autoRelease;
}
protected SimpleChannelInboundHandler(Class<? extends I> inboundMessageType) {
this(inboundMessageType, true);
}
// 获取iboundMEssageType参数的 类型 matcher, 自动release 为 true, 这是于ChannelInboundHandler 的不同点,后者需要手动释放
protected SimpleChannelInboundHandler(Class<? extends I> inboundMessageType, boolean autoRelease) {
this.matcher = TypeParameterMatcher.get(inboundMessageType);
this.autoRelease = autoRelease;
}
public boolean acceptInboundMessage(Object msg) throws Exception {
return this.matcher.match(msg);
}
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean release = true;
try {
// 如果接收到的参数是匹配类型,则处理
if (this.acceptInboundMessage(msg)) {
this.channelRead0(ctx, msg);
} else {
// 不匹配交给下一个handler 处理
release = false;
ctx.fireChannelRead(msg);
}
} finally {
if (this.autoRelease && release) {
// 引用计数减一
ReferenceCountUtil.release(msg);
}
}
}
// 由子类实现
protected abstract void channelRead0(ChannelHandlerContext var1, I var2) throws Exception;
}
事例:
/**
* @Author Mario
* @Date 2022-03-24 19:42
* @Version :
* @Description : 专门处理LoginRequestPacket 对象的请求,处理不了的直接传给下一个handler, 避免过多的if/else 处理不同的请求
*/
public class LoginRequestHandler extends SimpleChannelInboundHandler<LoginRequestPacket> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, LoginRequestPacket packet) throws Exception {
LoginResponsePacket loginResponsePacket = new LoginResponsePacket();
loginResponsePacket.setVersion(packet.getVersion());
if (valid(packet)) {
// 校验成功
loginResponsePacket.setSuccess(true);
System.out.println(new Date() + ": 登录成功");
} else {
// 失败
loginResponsePacket.setReason("账号密码不正确");
loginResponsePacket.setSuccess(false);
System.out.println(new Date() + ": 登录失败");
}
// 登录响应
// ByteBuf out = PacketCodeC.INSTANCE.encode(ctx.alloc(), loginResponsePacket);
ctx.channel().writeAndFlush(loginResponsePacket);
}
}
�