`
384444165
  • 浏览: 258783 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

深入阅读Mina源码(1) —— 小试牛刀,过滤器介绍

阅读更多

(ps:写完后觉着第一博还是应该说一下Mina的简介,就附上了0部分吧)

 

0. Mina框架简介 

 

    MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架。通过使用MINA框架可以可以省下处理底层I/O和线程并发等复杂工作,开发人员能够把更多的精力投入到业务设计和开发当中。MINA框架的应用比较广泛,应用的开源项目有Apache Directory、AsyncWeb、Apache Qpid、QuickFIX/J、Openfire、SubEthaSTMP、red5等。

    MINA框架的特点有:基于java NIO类库开发;采用非阻塞方式的异步传输;事件驱动;支持批量数据传输;支持TCP、UDP协议;控制反转的设计模式(支持Spring);采用优雅的松耦合架构;可灵活的加载过滤器机制;单元测试更容易实现;可自定义线程的数量,以提高运行于多处理器上的性能;采用回调的方式完成调用,线程的使用更容易。 

 

1. 引言

 

    近期的项目需要用到Mina,比较粗浅的在上层简单的搭建自己的项目,但是有种非常疑惑并且没有安全感的想法,就决定看下Mina的源码,并且网络部分的知识还是很重要的。第一次写源码分析的博客,也没有经验,不知道怎么说好,是不是需要细致摄入。我就避开入门和介绍部分,直接分析源码了,可能比较细微一点,也留作自己日后查看。(ps:如果要找Mina的介绍、入门相关的博客在iteye一搜就会有很多相关的介绍的,可以先看一下整体框架和基本的使用方法,方便理解)

    直接看源码可能会有找不到头绪的事情,站在巨人的肩膀上还是很好的方法,我选择了这个博客,先给出作者的地址,我会首先按照作者的思路分成四部分介绍,如果需要补充在增加文章,还是很推荐这几篇文章,有些作者说的清楚的我就不再重复描述,但是对于有些说的不清楚,或UML图有问题的我会说明一下,做少量的引用。


    http://wslfh2005.iteye.com/ 作者有四篇文章,不再详细列出,


    如果查看了Mina的入门博客,或者官方文档肯定对于类似下面这个图比较熟悉了,可以很清楚的看到IoFileterChain的过滤层,Mina对三层进行了很好的分离,使得连接维护,信息的预处理,逻辑处理很好的分离。我们首先来单个模块剥离,按照推荐的博客的顺序首先介绍过滤器层。

 

 

2.Mina过滤器机制的实现

 

 

 Mina的核心代码都在core中,包结构也很清晰,此部分代码都在core.filterchain中,目录下有一下几个类:

 

   

 

最重要的基础类和接口是:IoFilter、IoFilterChain、DefaultIoFilterChain。

这个图和引用的博客的图都不能很好的看出来这些文件的直接关系,下面就先看一下,有个直观认识

 

 

2.1 IoFilter

 

    看一下IoFilter定义的方法,可以把IoFilter简单的分成两部分。

    一部分是跟IoFilterChain相关的,在添加、删除相应的Filter之后调用,如:

 

 

/**
     * Invoked before this filter is added to the specified <tt>parent</tt>.
     * Please note that this method can be invoked more than once if
     * this filter is added to more than one parents.  This method is not
     * invoked before {@link #init()} is invoked.
     *
     * @param parent the parent who called this method
     * @param name the name assigned to this filter
     * @param nextFilter the {@link NextFilter} for this filter.  You can reuse
     *                   this object until this filter is removed from the chain.
     */
    void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
 

    另一部分是跟消息处理相关的,如:

 

 

/**
     * Filters {@link IoHandler#messageReceived(IoSession,Object)}
     * event.
     */
    void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception;
 

    其他就是跟初始化、销毁等相关的操作了。


    可以看到IoFilter的实现类IoFilterAdapter中其实没有过多的实现其中细致的操作,在sessionCreated等session相关和Message相关的方法中相应的调用了nextFilter的对应方法完成消息的传递,作为父类,可以看到消息传递的影子了。

    这里最值得关注的部分在于IoFilter中其中定义了一个NextFilter接口,NextFilter包含了IoFilter中提到的两部分全部方法,没有包含最后提到的初始化、销毁等相关的代码,而且最奇怪的就是在IoFilterAdapter没有实现这个接口。观察这个包的类图和命名,可以想象的到在维护消息连的DefaultIoFilterChain中肯定实现了此接口,通过找到EntryImpl的构造函数中为nextFilter赋值的时候实现了此接口,先避开细节只看nextFilter

 

 

public void sessionCreated(IoSession session) {
        Entry nextEntry = EntryImpl.this.nextEntry;
        callNextSessionCreated(nextEntry, session);
}

private void callNextSessionCreated(Entry entry, IoSession session) {
        try {
            IoFilter filter = entry.getFilter();
            NextFilter nextFilter = entry.getNextFilter();
            filter.sessionCreated(nextFilter, session);
        } catch (Throwable e) {
            fireExceptionCaught(e);
        }
}

 

    这段代码直接反应了所有方法的实现,都是通过这一种方式实现了转发的作用,这也是整个NextFilter方法的作用,具体的业务逻辑依然在Filter中执行,相同的名字只是为了维持含义的一致性,NextFilter的实例则维护在EntryImpl。下面就进入IoFilterChain看一下这个类。

 

2.2 IoFilterChain

 

    下面就按照最直观的名字先来看IoFilterChain,接口用来构造一个容器管理所有的IoFilter,里面更细节的定义了一个Entry接口,来表示每个FilterChain中的节点,Entry定义的方法如下

 


    现有个直观的认识,可以看到entry内容非常少,作用就是完成了维护前后和本身的IoFilter的工作,使得所有的Entry通过自身中的记录组成了一条链。

通过之前的图可以看到DefaultIoFilterChain是Mina给出的IoFilterChain默认实现类,因此必然有Entry的实现,找到发现是EntryImpl,EntryImpl构造函数为:

    private EntryImpl(EntryImpl prevEntry, EntryImpl nextEntry, String name, IoFilter filter) 

    通过这个构造函数就可以看出是如何实现前面的接口的了,只是为什么需要preEntry呢,只是为了传入Filter吗,如果答案是是的话Mina肯定不会这么做的。这里又一次要看NextFilter这个接口的实现了,可以看到filterWrite和filterClose方法都是逆向传递的:

 

 

public void filterWrite(IoSession session, WriteRequest writeRequest) {
        Entry nextEntry = EntryImpl.this.prevEntry;
        callPreviousFilterWrite(nextEntry, session, writeRequest);
}

public void filterClose(IoSession session) {
        Entry nextEntry = EntryImpl.this.prevEntry;
        callPreviousFilterClose(nextEntry, session);
}

 


    这里就看到了为什么Mina要大费干戈,而不采用简单的方式实现,和这里NextFilter接口设计的精妙之处,第一张架构图中可以看到消息传递的双向性,不管是服务器和客户端,消息的接受和发送总是反方向进行的,起点也不同。而通过实现nextFilter接口其实就很好的封装了消息传递的顺序,仅仅在Entry一层去控制所有方法向上还是向下传递,而对于外部的消息连而言只需要调用跟Filter同名的方法即可,虽然这里看到了调用的Chain中带有Previous和Next的方法,但是实际上内部并没有做相应的行为,都是只简单的获取nextFilter,因为nextFilter中的方法已经定义了相应的向上和向下传递。至于为什么叫这个名字应该是为了很好的表明这些方法的顺序和含义,另外nextFilter中调用的Chain中的方法全部都是private,因此对子类理解和修改没有影响。(刚才代码中调用的callPreviousFilterWrite如下)

 

 

private void callPreviousFilterWrite(Entry entry, IoSession session, WriteRequest writeRequest) {
        try {
            IoFilter filter = entry.getFilter();
            NextFilter nextFilter = entry.getNextFilter();
            filter.filterWrite(nextFilter, session, writeRequest);
        } catch (Throwable e) {
            writeRequest.getFuture().setException(e);
            fireExceptionCaught(e);
        }
}

 

    前面主要说的entry和nextfilter,接下来就单纯的针对Chain来看一下做了什么事情。DefaultIoFilterChain中维护了一个header和tail,很容易想到的就是链表,刚才提到entry通过内部的维持其实很方便来实现这样的链表。因此DefaultIoFilterChain的作用就是维护链表、提供nextFilter调用的filter相关方法完成传递,最后TailFilter将消息传递给IOHandler处理。包括IoFilterChain接口中除了fire方法也只是定义了很多关于链表的操作(fire方法后面再说)。

 

2.3 IoFilterEvent

 

    该类继承IoEvent,完成基于事件的处理模型,当一个事件(比如接收到消息)发生后会触发相应的事件,进而调用过滤器链的消息处理功能进行消息的处理和转发。这也是下一节要说的,提到这个类,因为刚才漏下了IoFilterChain的一系列fire方法没有介绍,如果不说显得不太完整了,IoFilterEvent基本只为了一个fire方法,就是根据构造方法中传入的IoEvent事件的类型区调用相应的nextFilter的方法,这里只是为子类提供一种事件处理的机制,搜索一下此类,可以看到在实现具体的filter时有些地方用到了,去更好的完成Filter或基于事件的流程控制(core之外的包看的少,不多误导)。另外从IoFilterEvent中可以看到这个利用NextFilter时已经不可见消息传递的方向了。根据事件去传递,用chain中提供的fire系列方法也可以同样完成。这个类代码很少,就不再粘贴和介绍。

 

2.4 DefaultIoFilterChainBuilder和IoFilterChainBuilder

 

    接口就是builder机制,不多说。细说一下实现类,它是个builder机制,但是它完成了很多IoFIlterChain需要完成的工作,它直接利用并发包中的CopyOnWriteArrayList来提供一个chain的构造操作,并且尚未构建IoFIlterChain之前,是可以修改list中的filter的,整个list的维护都对用户可见。builder实现了自己的entry,但是相对来说很简单,没有再每个entry维持链接关系。


    继承自接口的主要是build方法:

 

 

public void buildFilterChain(IoFilterChain chain) throws Exception {
        for (Entry e : entries) {
            chain.addLast(e.getName(), e.getFilter());
        }
}

 

 

    只是简单地把entry交进去,那链接关系是怎么创建的呢。感兴趣可以看一下DefaultIoFilterChain的addLast,其中检查了可插入行后就调用了register方法。

 

 

private void register(EntryImpl prevEntry, String name, IoFilter filter) {
        EntryImpl newEntry = new EntryImpl(prevEntry, prevEntry.nextEntry, name, filter);

        try {
            filter.onPreAdd(this, name, newEntry.getNextFilter());
        } catch (Exception e) {
            throw new IoFilterLifeCycleException("onPreAdd(): " + name + ':' + filter + " in " + getSession(), e);
        }

        prevEntry.nextEntry.prevEntry = newEntry;
        prevEntry.nextEntry = newEntry;
        name2entry.put(name, newEntry);

        try {
            filter.onPostAdd(this, name, newEntry.getNextFilter());
        } catch (Exception e) {
            deregister0(newEntry);
            throw new IoFilterLifeCycleException("onPostAdd(): " + name + ':' + filter + " in " + getSession(), e);
        }
}

 

    register方法又把有用的参数构造了新的DefaultIoFilterChain自己实现的EntryImpl, 肯定记得这样就会产生新的nextFilter,来调用entry中存储的前后节点,从而完成了chain的组成。

 

 

2.5 IoFilterLifeCycleException

 

    最后exception只是继承了RuntimeException,没有做其他的事情,用来标明是infilter中onPostAdd、onPreAdd等在加入Chain之前的操作发生异常。

 

 

2.6 Conclusion

 

    此部分主要是介绍了core中的消息链实现的机制,下面还要继续深入阅读其他部分源码,继续分享。因为是按照单独的模块阅读的代码,可能存在一些短见和没认识到的机制。最后看完所有的之后再做一次整合的介绍,和一个Mina上层的demo案例。今天到这了,碎觉。

分享到:
评论

相关推荐

    MINA 协议解码过滤器

    在`mina src`压缩包中,可能包含MINA框架的源代码,你可以通过阅读这些源码来深入理解MINA的工作原理,特别是过滤器和解码器的实现。这对于学习MINA、理解和定制自己的网络服务非常有帮助。同时,结合提供的博客链接...

    MINA源码与例子

    通过阅读源码,你可以深入了解MINA的设计思想和实现细节,例如如何实现非阻塞I/O、过滤器链的工作原理、以及如何自定义协议编码解码器等。 学习MINA源码可以帮助你: 1. **理解网络编程**:MINA是基于Java NIO实现...

    apache-mina源码

    通过阅读和分析`apache-mina-2.0.16`的源码,我们可以深入理解MINA的设计思想,学习如何构建高效的网络服务,并能根据自己的需求定制和扩展MINA的功能。对于想要从事网络编程或系统架构设计的开发者来说,研究MINA...

    Mina源码解析

    1. **Mina的过滤器机制实现**: Mina的核心设计理念之一是过滤器链(Filter Chain),它借鉴了Servlet的过滤器模型。每个过滤器都可以在数据传输过程中进行拦截和处理,如数据编码、解码、安全检查等。过滤器之间...

    MINA源码分析,内涵类的讲解

    总结来说,MINA源码分析涉及了网络编程的基础概念,包括异步事件驱动、过滤器链、编码解码、会话管理等多个方面。通过深入理解这些核心组件,开发者可以更加灵活地构建高并发、高性能的网络应用。同时,MINA的源码也...

    mina 源码

    深入研究"apache-mina-2.0.4"源码,我们可以学习到MINA如何实现非阻塞I/O,过滤器链的构建和事件传播机制,以及如何定制和扩展MINA以满足特定需求。例如,可以查看IoSession的实现,了解其如何管理会话状态;研究...

    Mina2源码分析

    ### Mina2源码分析——核心模块解析 #### 概述 Mina2是一个高性能、可扩展的网络应用框架,支持多种传输协议如TCP、UDP等,并提供了丰富的API供开发者使用。本文旨在深入剖析Mina2的核心部分,帮助读者更好地理解和...

    mina源码+例子mina-2.0.0-M6.zip

    2. **分析源码**:通过阅读MINA的源码,了解其内部处理流程,如读写事件的处理、过滤器链的工作方式等。 3. **编写简单的应用**:从例子入手,创建一个简单的MINA服务器和客户端,理解它们之间的通信机制。 4. **...

    MINA 2.0.9源码

    通过阅读MINA 2.0.9的源码,你可以了解如何实现高效的网络通信,包括事件驱动的设计模式、多线程处理、数据包的拆分和组合,以及如何利用过滤器链实现复杂的功能。此外,源码分析还能帮助你掌握如何自定义Filter和...

    mina2.0源码svn地址

    ### mina2.0源码svn地址解析与详细介绍 #### 一、Mina2.0简介 Mina(Multi-threaded IO Network Architecture)是Apache软件基金会的一个开源项目,旨在为开发人员提供一个易于使用的高性能网络应用程序框架。Mina...

    Mina 框架源码解析-构建简单通信程序

    通过解析`HeartBeat`源码,我们可以学习到如何利用Mina构建通信程序,以及如何利用其强大的过滤器机制和事件驱动模型来处理复杂的网络任务。对于任何想要深入理解网络编程或构建高性能网络应用的人来说,Mina都是一...

    apache下的mina框架的源码

    通过阅读源码,你可以了解MINA如何实现这些功能,并学习如何自定义过滤器以满足特定需求。例如,你可以看到如何创建一个新的过滤器来实现数据压缩,或者如何实现一个自定义的协议解码器。此外,MINA的异步IO机制使得...

    Mina2.0框架源码剖析

    通过深入分析Mina2.0的源码,我们可以了解到其内部的事件驱动模型、网络通信机制以及如何通过过滤器和处理器来处理网络请求。这有助于我们更好地理解和利用Mina框架来开发高并发、高性能的网络应用。

    JAVA mina 框架源码

    深入研究Mina源码,我们可以学习到以下关键知识点: 1. **事件驱动模型**:Mina基于事件驱动模型,当网络事件发生时,如数据到达或连接建立,会触发相应的事件处理器,使得程序响应及时高效。 2. **异步编程**:...

    Mina 1.1.7 示例源码(apache.mina.example)

    这个示例集合是为了学习和交流而准备的,开发者可以通过分析源码了解Mina如何处理网络通信,如何构建过滤器链,以及如何实现自定义的协议编码解码器。同时,这些示例也提供了实际操作的机会,便于开发者在遇到问题...

    mina2 源码 mina

    对于有经验的开发者,深入源码可以提供对MINA内部机制的洞察,从而更好地优化和定制自己的网络服务。 总之,Apache MINA2是一个强大的网络应用框架,它的源码和实例是宝贵的教育资源,有助于提升Java网络编程能力,...

    mina框架源码及jar包

    深入研究Mina的源码可以帮助我们理解其内部工作原理,如事件驱动模型的实现、过滤器链的传递机制以及NIO的封装等。同时,源码中的各种设计模式和最佳实践也值得借鉴。 **应用场景:** Mina广泛应用于需要高效网络...

    Java mina2源码

    通过深入研究Mina2的源码,我们可以了解到如何优化网络通信性能,如何处理大规模并发连接,以及如何设计和实现自己的网络协议。源码分析还能帮助我们理解Java的多线程、并发控制和事件驱动编程等高级特性,提升我们...

    Mina 2.0快速入门与源码解析

    ### Mina 2.0快速入门与源码解析 #### Mina 2.0 快速入门 Mina 2.0 是一个基于Java NIO技术的高效、可伸缩的网络通信框架,广泛应用于服务器端开发。Mina 2.0 的设计目标是为开发者提供一个易于使用的API,使得...

    mina源码走读与实例

    ### MINA源码走读与实例 #### 一、MINA概述 ...以上就是关于MINA源码及其基本工作原理的介绍。MINA通过强大的抽象能力和丰富的接口设计,为开发者提供了一种简单高效的方式来构建高性能、高扩展性的网络通信应用。

Global site tag (gtag.js) - Google Analytics