最近在学习netty,netty原生代码看起来挺复杂,为了让自己理解起来容易一点,对netty中的部件进行了简化,这里介绍的是netty的pipeline。
首先看一下简化后的代码结构
pipeline就像一个双向链表,放着head和tail两个链表节点,提供addLast和addFirst等方法,向链表中添加数据
context是链表的一个个的node节点,包含prev和next指针,以及存放的实际的数据,即handler
pipeline的fireChannelRead等方法像是遍历链表节点的作用
invoker是netty中使用到的,在这里的作用其实没有体现的很明显
context内容
package com.mylovin.netty.nettycode.pipe.context;
import com.mylovin.netty.nettycode.pipe.handler.Handler;
import com.mylovin.netty.nettycode.pipe.invoker.DefaultInvoker;
public class Context {
public Context next;
public Context prev;
public Handler handler;
public DefaultInvoker invoker;
DefaultInvoker invoker() {
return this.invoker == null ? new DefaultInvoker() : this.invoker;
}
public void fireChannelRead() {
Context next = this.next;
if (null != next) {
next.invoker().invokeChannelRead(next);
}
}
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
handler
package com.mylovin.netty.nettycode.pipe.handler;
import com.mylovin.netty.nettycode.pipe.context.Context;
public interface Handler {
void fireChannelRead(Context context);
}
DefaultInvoker
package com.mylovin.netty.nettycode.pipe.invoker;
import com.mylovin.netty.nettycode.pipe.context.Context;
public class DefaultInvoker {
public void invokeChannelRead(Context context) {
InvokerUtil.invokeChannelReadNow(context);
}
}
InvokerUtil
package com.mylovin.netty.nettycode.pipe.invoker;
import com.mylovin.netty.nettycode.pipe.context.Context;
public class InvokerUtil {
public static void invokeChannelReadNow(Context context) {
context.handler.fireChannelRead(context);
}
}
pipeline
package com.mylovin.netty.nettycode.pipe.pipeline;
import com.mylovin.netty.nettycode.pipe.context.Context;
import com.mylovin.netty.nettycode.pipe.handler.Handler;
public class DefaultPipeline {
private Context headContext;
private Context tailContext;
public DefaultPipeline() {
this.headContext = new HeadContext();
this.tailContext = new TailContext();
this.headContext.next = this.tailContext;
this.tailContext.prev = this.headContext;
}
public void addLast(Handler handler) {
Context ctx = new Context();
ctx.setHandler(handler);
Context tmp = this.tailContext.prev;
tmp.next = ctx;
ctx.prev = tmp;
ctx.next = this.tailContext;
this.tailContext.prev = ctx;
}
public void fireChannelRead() {
this.headContext.fireChannelRead();
}
private class HeadContext extends Context {
public HeadContext() {
super();
this.handler = new Handler() {
@Override
public void fireChannelRead(Context context) {
context.fireChannelRead();
}
};
}
}
private class TailContext extends Context {
public TailContext() {
super();
this.handler = new Handler() {
@Override
public void fireChannelRead(Context context) {
context.fireChannelRead();
}
};
}
}
}
main中调用
package com.mylovin.netty.nettycode.pipe;
import com.mylovin.netty.nettycode.pipe.handler.CustomHandlerOne;
import com.mylovin.netty.nettycode.pipe.handler.CustomHandlerTwo;
import com.mylovin.netty.nettycode.pipe.pipeline.DefaultPipeline;
/**
* 解析:
* 1、pipeline就像一个双向链表,放着head和tail两个链表节点,提供addLast和addFirst等方法,向链表中添加数据
* 2、context是链表的一个个的node节点,包含prev和next指针,以及存放的实际的数据,即handler
* 3、pipeline的fireChannelRead等方法像是遍历链表节点的作用
* 4、invoker是netty中使用到的,在这里的作用其实没有体现的很明显
*/
public class Main {
public static void main(String[] args) {
DefaultPipeline pipeline = new DefaultPipeline();
pipeline.addLast(new CustomHandlerOne());
pipeline.addLast(new CustomHandlerTwo());
pipeline.fireChannelRead();
}
}