简述
在netty中ChannelInboundHandler接口用于处理入站事件,即外部向netty应用程序发起的请求。ChannelInboundHandlerAdapter是ChannelInboundHandler的实现类,而SimpleChannelInboundHandler是ChannelInboundHandlerAdapter的一个子类 SimpleChannelInboundHandler中有一个抽象方法channelRead0(ChannelHandlerContext var1, I var2),SimpleChannelInboundHandler的使用方法便是创建一个具体的处理类,继承SimpleChannelInboundHandler,同时重写channelRead0(ChannelHandlerContext var1, I var2)方法,内部实现具体的处理逻辑(代码块中以NettyRpcClientHandler为例子)
NettyRpcClientHandler
public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler {
......
}
SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter {
......
}
public class NettyRpcClientHandler extends SimpleChannelInboundHandler<RpcMessage> {
private final ConcurrentHashMap<String, CompletableFuture<RpcResponse<Object>>> pendingRequests;
public NettyRpcClientHandler(ConcurrentHashMap<String, CompletableFuture<RpcResponse<Object>>> pendingRequests) {
this.pendingRequests = pendingRequests;
}
//若是消息体的类型是泛型类型RpcMessage便执行channelRead0方法
@Override
protected void channelRead0(ChannelHandlerContext ctx, RpcMessage msg) {
log.debug("Client received message: {}", msg);
if (msg.getMessageType() == RpcMessage.MessageType.RESPONSE.getCode()) {
RpcResponse<Object> response = (RpcResponse<Object>) msg.getData();
CompletableFuture<RpcResponse<Object>> future = pendingRequests.remove(response.getRequestId());
if (future != null) {
future.complete(response);
} else {
log.warn("Received response for unknown request: {}", response.getRequestId());
}
}
}
......
}
SimpleChannelInboundHandler对 ChannelInboundHandlerAdapter 的增强主要体现在三个方面 一、类型匹配和自动类型转换:根据泛型的类型,若是传入的消息体类型为泛型的类型,则将消息体类型转换为泛型的类型,同时执行channelread0方法,若是不符合,执行ctx.fireChannelRead(),将消息题抛给处理器链中的其他处理器处理。
二、自动释放资源:SimpleChannelInboundHandler在处理完消息后,会根据autoRelease属性的值自动释放消息对象占用的资源。这是通过调用ReferenceCountUtil.release(msg)实现的,ChannelInboundHandlerAdapter需要开发者在适当的时候手动释放资源。
三、简化开发流程:SimpleChannelInboundHandler提供了类型匹配、自动类型转换和自动资源释放等功能,它简化了入站消息的处理流程。开发者只需要继承SimpleChannelInboundHandler并实现channelRead0方法即可.
源码解析(看注释)
channelRead(ChannelHandlerContext ctx, Object msg)根据消息体类是否为泛型的类,执行不同方法
channelRead
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//是否进行释放的标记
boolean release = true;
try {
//acceptInboundMessage(msg)判断msg类型是否为泛型类型
if (this.acceptInboundMessage(msg)) {
I imsg = msg;//进行类型转换
this.channelRead0(ctx, imsg);//执行业务处理代码
} else {
//标记为不自动释放
release = false;
//传递给其他处理器处理
ctx.fireChannelRead(msg);
}
} finally {
if (this.autoRelease && release) {
//释放
ReferenceCountUtil.release(msg);
}
}
}
channelRead0(ChannelHandlerContext ctx, RpcMessage msg)消息处理逻辑
channelRead0
@Override
//以rpc为例子的channelRead0方法实现
protected void channelRead0(ChannelHandlerContext ctx, RpcMessage msg) {
log.debug("Client received message: {}", msg);
if (msg.getMessageType() == RpcMessage.MessageType.RESPONSE.getCode()) {
RpcResponse<Object> response = (RpcResponse<Object>) msg.getData();
CompletableFuture<RpcResponse<Object>> future = pendingRequests.remove(response.getRequestId());
if (future != null) {
future.complete(response);
} else {
log.warn("Received response for unknown request: {}", response.getRequestId());
}
}
}
acceptInboundMessage(Object msg)具体判断
acceptInboundMessage
//默认构造函数
protected SimpleChannelInboundHandler() {
this(true);
}
//获取对应泛型的类型比较器matcher
protected SimpleChannelInboundHandler(boolean autoRelease) {
//具体内部源码看下一个方法源码
this.matcher = TypeParameterMatcher.find(this, SimpleChannelInboundHandler.class, "I");
this.autoRelease = autoRelease;
}
public boolean acceptInboundMessage(Object msg) throws Exception {
//返回类判断结果
return this.matcher.match(msg);
}
//具体的matcher类
private static final class ReflectiveMatcher extends TypeParameterMatcher {
private final Class<?> type;
ReflectiveMatcher(Class<?> type) {
this.type = type;
}
//检查对象是否为该泛型类的实例或子类实例
public boolean match(Object msg) {
return this.type.isInstance(msg);
}
}
find(Object object, Class<?> parametrizedSuperclass, String typeParamName)获取泛型对应的matcher
TypeParameterMatcher中的find()方法
public static TypeParameterMatcher find(Object object, Class<?> parametrizedSuperclass, String typeParamName) {
Map<Class<?>, Map<String, TypeParameterMatcher>> findCache = InternalThreadLocalMap.get().typeParameterMatcherFindCache();
//获取最下层的子类实例的类,也就是NettyRpcClientHandler.getClass;
Class<?> thisClass = object.getClass();
//获取以NettyRpcClientHandler。class为key 的matcher存储表
Map<String, TypeParameterMatcher> map = (Map)findCache.get(thisClass);
if (map == null) {
map = new HashMap();
findCache.put(thisClass, map);
}
//获取以泛型参数名typeParamName:'I'为key的存储的matcher
TypeParameterMatcher matcher = (TypeParameterMatcher)((Map)map).get(typeParamName);
if (matcher == null) {
//若是matcher 为空,构建对应的matcher
matcher = get(find0(object, parametrizedSuperclass, typeParamName));
((Map)map).put(typeParamName, matcher);
}
//返回matcher
return matcher;
}
find0(Object object, Class<?> parametrizedSuperclass, String typeParamName)//获取泛型对应的class
find0
private static Class<?> find0(Object object, Class<?> parametrizedSuperclass, String typeParamName) {
Class<?> thisClass = object.getClass();
Class<?> currentClass = thisClass;
do {
//获取父类为SimpleChannelInboundHandler的类:currentClass
while(currentClass.getSuperclass() != parametrizedSuperclass) {
currentClass = currentClass.getSuperclass();
if (currentClass == null) {
return fail(thisClass, typeParamName);
}
}
int typeParamIndex = -1;
//获取泛型列表
TypeVariable<?>[] typeParams = currentClass.getSuperclass().getTypeParameters();
//typeParamIndex设置为需要的泛型(即'I')在泛型列表中的index
for(int i = 0; i < typeParams.length; ++i) {
if (typeParamName.equals(typeParams[i].getName())) {
typeParamIndex = i;
break;
}
}
//typeParamIndex < 0说明这个泛型不存在于泛型列表
if (typeParamIndex < 0) {
throw new IllegalStateException("unknown type parameter '" + typeParamName + "': " + parametrizedSuperclass);
}
//获取currentclass的泛型父类,判断是否带有泛型,若是不带有则直接返回Object.class
Type genericSuperType = currentClass.getGenericSuperclass();
if (!(genericSuperType instanceof ParameterizedType)) {
return Object.class;
}
//获取泛型列表中,typename为'I'的泛型
Type[] actualTypeParams = ((ParameterizedType)genericSuperType).getActualTypeArguments();
Type actualTypeParam = actualTypeParams[typeParamIndex];
//如果泛型参数本身是一个参数化类型(例如 List<String>),获取其原始类型(List)
if (actualTypeParam instanceof ParameterizedType) {
actualTypeParam = ((ParameterizedType)actualTypeParam).getRawType();
}
//如果泛型参数是一个具体的类类型(例如 String),直接返回这个类类型
if (actualTypeParam instanceof Class) {
return (Class)actualTypeParam;
}
//如果泛型参数是一个数组类型(例如 List<String>[]),获取数组的组件类型
if (actualTypeParam instanceof GenericArrayType) {
Type componentType = ((GenericArrayType)actualTypeParam).getGenericComponentType();
//如果组件类型是参数化类型,获取其原始类型
if (componentType instanceof ParameterizedType) {
componentType = ((ParameterizedType)componentType).getRawType();
}
//如果组件类型是具体类类型,创建一个空数组并返回其类类型
if (componentType instanceof Class) {
return Array.newInstance((Class)componentType, 0).getClass();
}
}
//如果泛型参数既不是具体类类型,也不是数组类型,那么它可能是一个类型变量(例如 T)如果不是类型变量,调用 fail 方法处理错误
if (!(actualTypeParam instanceof TypeVariable)) {
return fail(thisClass, typeParamName);
}
//获取类型变量的声明。如果声明不是类类型,返回 Object.class
TypeVariable<?> v = (TypeVariable)actualTypeParam;
if (!(v.getGenericDeclaration() instanceof Class)) {
return Object.class;
}
//更新当前类和父类,以便继续解析。
currentClass = thisClass;
parametrizedSuperclass = (Class)v.getGenericDeclaration();
typeParamName = v.getName();
} while(parametrizedSuperclass.isAssignableFrom(thisClass));
return Object.class;
}
TypeParameterMatcher get(Class<?> parameterType)获取对应类的matcher
get
//创建一个默认返回true 的matcher
private static final TypeParameterMatcher NOOP = new TypeParameterMatcher() {
public boolean match(Object msg) {
return true;
}
};
public static TypeParameterMatcher get(Class<?> parameterType) {
//尝试从缓存中获取泛型类对应的matcher
Map<Class<?>, TypeParameterMatcher> getCache = InternalThreadLocalMap.get().typeParameterMatcherGetCache();
TypeParameterMatcher matcher = (TypeParameterMatcher)getCache.get(parameterType);
if (matcher == null) {
if (parameterType == Object.class) {
//由于泛型的类是Object,说明所有的类都可以通过matcher的判断,所以直接返回默认返回true的matcher
matcher = NOOP;
} else {
//new一个通过反射判断是否符合泛型类的matcher
matcher = new ReflectiveMatcher(parameterType);
}
getCache.put(parameterType, matcher);
}
return (TypeParameterMatcher)matcher;
}
源码
NettyRpcClientHandler
NettyRpcClientHandler
public class NettyRpcClientHandler extends SimpleChannelInboundHandler<RpcMessage> {
private final ConcurrentHashMap<String, CompletableFuture<RpcResponse<Object>>> pendingRequests;
public NettyRpcClientHandler(ConcurrentHashMap<String, CompletableFuture<RpcResponse<Object>>> pendingRequests) {
this.pendingRequests = pendingRequests;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, RpcMessage msg) {
log.debug("Client received message: {}", msg);
if (msg.getMessageType() == RpcMessage.MessageType.RESPONSE.getCode()) {
RpcResponse<Object> response = (RpcResponse<Object>) msg.getData();
CompletableFuture<RpcResponse<Object>> future = pendingRequests.remove(response.getRequestId());
if (future != null) {
future.complete(response);
} else {
log.warn("Received response for unknown request: {}", response.getRequestId());
}
}
}
}
SimpleChannelInboundHandler
SimpleChannelInboundHandler
public absSimpleChannelInboundHandlertract 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);
}
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)) {
I imsg = msg;
this.channelRead0(ctx, imsg);
} else {
release = false;
ctx.fireChannelRead(msg);
}
} finally {
if (this.autoRelease && release) {
ReferenceCountUtil.release(msg);
}
}
}
protected abstract void channelRead0(ChannelHandlerContext var1, I var2) throws Exception;
}
TypeParameterMatcher
TypeParameterMatcher
public abstract class TypeParameterMatcher {
private static final TypeParameterMatcher NOOP = new TypeParameterMatcher() {
public boolean match(Object msg) {
return true;
}
};
public static TypeParameterMatcher get(Class<?> parameterType) {
Map<Class<?>, TypeParameterMatcher> getCache = InternalThreadLocalMap.get().typeParameterMatcherGetCache();
TypeParameterMatcher matcher = (TypeParameterMatcher)getCache.get(parameterType);
if (matcher == null) {
if (parameterType == Object.class) {
matcher = NOOP;
} else {
matcher = new ReflectiveMatcher(parameterType);
}
getCache.put(parameterType, matcher);
}
return (TypeParameterMatcher)matcher;
}
public static TypeParameterMatcher find(Object object, Class<?> parametrizedSuperclass, String typeParamName) {
Map<Class<?>, Map<String, TypeParameterMatcher>> findCache = InternalThreadLocalMap.get().typeParameterMatcherFindCache();
Class<?> thisClass = object.getClass();
Map<String, TypeParameterMatcher> map = (Map)findCache.get(thisClass);
if (map == null) {
map = new HashMap();
findCache.put(thisClass, map);
}
TypeParameterMatcher matcher = (TypeParameterMatcher)((Map)map).get(typeParamName);
if (matcher == null) {
matcher = get(find0(object, parametrizedSuperclass, typeParamName));
((Map)map).put(typeParamName, matcher);
}
return matcher;
}
private static Class<?> find0(Object object, Class<?> parametrizedSuperclass, String typeParamName) {
Class<?> thisClass = object.getClass();
Class<?> currentClass = thisClass;
do {
while(currentClass.getSuperclass() != parametrizedSuperclass) {
currentClass = currentClass.getSuperclass();
if (currentClass == null) {
return fail(thisClass, typeParamName);
}
}
int typeParamIndex = -1;
TypeVariable<?>[] typeParams = currentClass.getSuperclass().getTypeParameters();
for(int i = 0; i < typeParams.length; ++i) {
if (typeParamName.equals(typeParams[i].getName())) {
typeParamIndex = i;
break;
}
}
if (typeParamIndex < 0) {
throw new IllegalStateException("unknown type parameter '" + typeParamName + "': " + parametrizedSuperclass);
}
Type genericSuperType = currentClass.getGenericSuperclass();
if (!(genericSuperType instanceof ParameterizedType)) {
return Object.class;
}
Type[] actualTypeParams = ((ParameterizedType)genericSuperType).getActualTypeArguments();
Type actualTypeParam = actualTypeParams[typeParamIndex];
if (actualTypeParam instanceof ParameterizedType) {
actualTypeParam = ((ParameterizedType)actualTypeParam).getRawType();
}
if (actualTypeParam instanceof Class) {
return (Class)actualTypeParam;
}
if (actualTypeParam instanceof GenericArrayType) {
Type componentType = ((GenericArrayType)actualTypeParam).getGenericComponentType();
if (componentType instanceof ParameterizedType) {
componentType = ((ParameterizedType)componentType).getRawType();
}
if (componentType instanceof Class) {
return Array.newInstance((Class)componentType, 0).getClass();
}
}
if (!(actualTypeParam instanceof TypeVariable)) {
return fail(thisClass, typeParamName);
}
TypeVariable<?> v = (TypeVariable)actualTypeParam;
if (!(v.getGenericDeclaration() instanceof Class)) {
return Object.class;
}
currentClass = thisClass;
parametrizedSuperclass = (Class)v.getGenericDeclaration();
typeParamName = v.getName();
} while(parametrizedSuperclass.isAssignableFrom(thisClass));
return Object.class;
}
private static Class<?> fail(Class<?> type, String typeParamName) {
throw new IllegalStateException("cannot determine the type of the type parameter '" + typeParamName + "': " + type);
}
public abstract boolean match(Object var1);
TypeParameterMatcher() {
}
private static final class ReflectiveMatcher extends TypeParameterMatcher {
private final Class<?> type;
ReflectiveMatcher(Class<?> type) {
this.type = type;
}
public boolean match(Object msg) {
return this.type.isInstance(msg);
}
}
}