From ba658a7baa8af908468ba49075c693675fd8d1c9 Mon Sep 17 00:00:00 2001 From: AmyliaY <471816751@qq.com> Date: Mon, 2 Mar 2020 23:46:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=A8=A1=E5=BC=8F=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=20=E8=B4=A3=E4=BB=BB=E9=93=BE?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E7=9A=84=E8=AE=B2=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 + ...源码中学习设计模式(行为型).md | 140 +++++++++++++++++- images/DesignPattern/责任链模式.png | Bin 0 -> 14106 bytes ...nelPipeline责任链事件处理过程.png | Bin 0 -> 25748 bytes 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 images/DesignPattern/责任链模式.png create mode 100644 images/Netty/ChannelPipeline责任链事件处理过程.png diff --git a/README.md b/README.md index 948dfd3..122a09b 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,11 @@ ## Tomcat - 努力编写中... +## 番外篇(JDK 1.8) +- [HashMap 源码赏析]() +- [ConcurrentHashMap 源码赏析]() +- [String 源码赏析]() + ## 学习心得 ### 个人经验 - [初级开发者应该从 Spring 源码中学什么](docs/LearningExperience/PersonalExperience/初级开发者应该从spring源码中学什么.md) diff --git a/docs/LearningExperience/DesignPattern/从Spring及Mybatis框架源码中学习设计模式(行为型).md b/docs/LearningExperience/DesignPattern/从Spring及Mybatis框架源码中学习设计模式(行为型).md index 0c8fe2f..050f4a4 100644 --- a/docs/LearningExperience/DesignPattern/从Spring及Mybatis框架源码中学习设计模式(行为型).md +++ b/docs/LearningExperience/DesignPattern/从Spring及Mybatis框架源码中学习设计模式(行为型).md @@ -1,6 +1,7 @@ 设计模式是解决问题的方案,从大神的代码中学习对设计模式的使用,可以有效提升个人编码及设计代码的能力。本系列博文用于总结阅读过的框架源码(Spring系列、Mybatis)及JDK源码中 所使用过的设计模式,并结合个人工作经验,重新理解设计模式。 -本篇博文主要看一下行为型的几个设计模式,即,策略模式、模板方法模式、迭代器模式 及 观察者模式。 +本篇博文主要看一下行为型的几个设计模式,即,策略模式、模板方法模式、迭代器模式、观察者模式 及 责任链模式。 + ## 策略模式 #### 个人理解 @@ -1072,4 +1073,141 @@ public class Observable { return obs.size(); } } +``` + +## 责任链模式 +一般用在消息请求的处理上,如 Netty 的 ChannelHandler组件,Tomcat 对 HTTP 请求的处理。我们当然可以将 请求的处理逻辑都写在一个类中,但这个类会非常雕肿且不易于维护,不符合开发封闭原则。 + +在责任链模式中,将上述臃肿的请求处理逻辑 拆分到多个 功能逻辑单一的 Handler 处理类中,这样我们就可以根据业务需求,将多个 Handler 对象组合成一条责任链,实现请求的处理。在一条责任链中,每个 Handler对象 都包含对下一个 Handler对象 的引用,一个 Handler对象 处理完请求消息(或不能处理该请求)时, 会把请求传给下一个 Handler对象 继续处理,依此类推,直至整条责任链结束。简单看一下责任链模式的类图。 + +![avatar](/images/DesignPattern/责任链模式.png) + +#### Netty 中的应用 +在 Netty 中,将 Channel 的数据管道抽象为 ChannelPipeline,消息在 ChannelPipeline 中流动和传递。ChannelPipeline 是 ChannelHandler 的容器,持有 I/O事件拦截器 ChannelHandler 的链表,负责对 ChannelHandler 的管理和调度。由 ChannelHandler 对 I/O事件 进行拦截和处理,并可以通过接口方便地新增和删除 ChannelHandler 来实现不同业务逻辑的处理。下图是 ChannelPipeline源码中描绘的责任链事件处理过程。 +![avatar](/images/Netty/ChannelPipeline责任链事件处理过程.png) +其具体过程处理如下: + +1. 底层SocketChannel 的 read方法 读取 ByteBuf,触发 ChannelRead事件,由 I/O线程 NioEventLoop 调用 ChannelPipeline 的 fireChannelRead()方法,将消息传输到 ChannelPipeline中。 + +2. 消息依次被 InboundHandler 1、InboundHandler 2 … InboundHandler N 拦截处理,在这个过程中,任何 ChannelHandler 都可以中断当前的流程,结束消息的传递。 + +3. 当调用 ChannelHandlerContext 的 write()方法 发送消息,消息从 OutbountHandler 1 开始 一直到 OutboundHandler N,最终被添加到消息发送缓冲区中等待刷新和发送。 + +在 Netty 中将事件根据源头的不同分为 InBound事件 和 OutBound事件。InBound事件 通常由 I/O线程 触发,例如 TCP链路 建立和关闭、读事件等等,分别会触发相应的事件方法。而 OutBound事件 则一般由用户主动发起的 网络I/O操作,例如用户发起的连接操作,绑定操作和消息发送操作等,也会分别触发相应的事件方法。由于 netty 中提供了一个抽象类 ChannelHandlerAdapter,它默认不处理拦截的事件。所以,在实际编程过程中,我们只需要继承 ChannelHandlerAdapter,在我们的 自定义Handler 中覆盖业务关心的事件方法即可。其源码如下。 +```java +/** + * 它扮演了 责任链模式中的 Client角色,持有 构造 并使用 ChannelHandler责任链 + */ +public interface ChannelPipeline + extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable> { + + ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler); + + ChannelPipeline addLast(String name, ChannelHandler handler); + + ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler); + + ChannelPipeline addFirst(ChannelHandler... handlers); + + ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers); + + ChannelPipeline addLast(ChannelHandler... handlers); + + ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers); + + ChannelPipeline remove(ChannelHandler handler); + + ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler); + + ChannelHandler get(String name); + + @Override + ChannelPipeline fireChannelRegistered(); + + @Override + ChannelPipeline fireChannelUnregistered(); + + @Override + ChannelPipeline fireChannelActive(); + + @Override + ChannelPipeline fireChannelInactive(); + + @Override + ChannelPipeline fireExceptionCaught(Throwable cause); + + @Override + ChannelPipeline fireUserEventTriggered(Object event); + + @Override + ChannelPipeline fireChannelRead(Object msg); + + @Override + ChannelPipeline fireChannelReadComplete(); + + @Override + ChannelPipeline fireChannelWritabilityChanged(); +} + + +/** + * ChannelHandler本身并不是链式结构的,链式结构是交由 ChannelHandlerContext + * 进行维护的 + */ +public interface ChannelHandler { + + void handlerAdded(ChannelHandlerContext ctx) throws Exception; + + void handlerRemoved(ChannelHandlerContext ctx) throws Exception; + + void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;x +} + + +/** + * DefaultChannelHandlerContext 持有一个 final 的 ChannelHandler对象, + * 其父类 AbstractChannelHandlerContext 是一个双向链表的结构设计,这样就保证了 + * ChannelHandler 的 责任链式处理 + */ +final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext { + + private final ChannelHandler handler; + + DefaultChannelHandlerContext( + DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) { + super(pipeline, executor, name, isInbound(handler), isOutbound(handler)); + if (handler == null) { + throw new NullPointerException("handler"); + } + this.handler = handler; + } + + @Override + public ChannelHandler handler() { + return handler; + } + + private static boolean isInbound(ChannelHandler handler) { + return handler instanceof ChannelInboundHandler; + } + + private static boolean isOutbound(ChannelHandler handler) { + return handler instanceof ChannelOutboundHandler; + } +} + + +/** + * 很容易看出来,这是一个双向链表的结构设计 + */ +abstract class AbstractChannelHandlerContext extends DefaultAttributeMap + implements ChannelHandlerContext, ResourceLeakHint { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractChannelHandlerContext.class); + volatile AbstractChannelHandlerContext next; + volatile AbstractChannelHandlerContext prev; + + ...... + +} ``` \ No newline at end of file diff --git a/images/DesignPattern/责任链模式.png b/images/DesignPattern/责任链模式.png new file mode 100644 index 0000000000000000000000000000000000000000..424ca11dfe3454b01dc8f99b3e73cd4d89ce400e GIT binary patch literal 14106 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 bWWw>8nQMZXtbz}l5iroQDz|f`O`rT1NGbA~ literal 0 HcmV?d00001 diff --git a/images/Netty/ChannelPipeline责任链事件处理过程.png b/images/Netty/ChannelPipeline责任链事件处理过程.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f3224172a694da8dfba528ef787319e98e80b3 GIT binary patch literal 25748 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 B45k18 literal 0 HcmV?d00001