接上一讲对mina的简单应用和对mina服务端和客户端中几个重要的技术知识点的理解后,今天着重对mina服务端的NioSocketAcceptor 进行学习。
说这个玩意之前,先整体上看一下在mina框架中NioSocketAcceptor和NioSocketConnector 这两个玩意的整体代码结构:
从上面的代码结构我做如下的解释:
服务端通过创建一个NioSocketAcceptor来接受请求,客户端通过创建NioSocketConnector来连接服务端并发送请求。
IoService是对于服务器端接受连接和客户端发起连接两类行为的一个抽象。IoServer用来执行真正的 I/O 操作,以及管理 I/O 会话。两个子接口为IoAcceptor和IoConnector。IoAcceptor用来接受连接,与客户端进行通讯。IoConnector用来发起连接,与服务端进行通讯。IoAcceptor和IoConnector都分别有基于TCP/IP协议协议,UDP/IP协议以及虚拟机管道通讯的子接口。
上面是NioSocketAcceptor和NioSocketConnector的一个类的结构,现在我们从服务端先来说:先看一下服务端的代码继承和接口:
在这里我们知道我们想使用mina的时候就是先从一个NioSocketAcceptor定义开始,定义NioSocketAcceptor的时候需要绑定或者指定其对应的过滤器,IOHandler处理器,线程池等等。从源码中我们可以知道NioSocketAcceptor的方法的入口是linstener,结束的出口是dispose()。哪我们就从一个NioSocketAcceptor的定义开始。
首先看一下我们定义开始的地方跟我们上一讲中实现一个mina服务端编写是一样的。在这里我们重点来看我们实现了一个MinaSocketServer的接口,而这个接口中只有两个方法
我们从listener的方法中可以看到是这样的实现,定义一个NioSocketAcceptor,指定过滤链,iohandler处理器,绑定端口。我们就先从初始化的NioSocketAcceptor来说,先看NioSocketAcceptor的new操作》
我们可以看到对NioSocketAcceptor的初始化创建的时候是传入了一个SimpleIoProcessorPool对象,而其中有NioProcessor和一个线程池,对这两个的解释我们先放到后面,先来看nioSocketAcceptor的构造函数源码:
在这个代码中我们需要注意一下哈 这里的这个selector是用volatile来修饰的,这样在线程每次使用的时候,都会读取变量修改后的最的值。想想这是为什么。或者在面试的时候人家问你在什么地方见到过这个词,知道了吧,这就是我们读源码的好处,到时候说不上你的面试官都不知道^_^
在这里我们只是看到的nioSocketAcceptor的实现:下面是父类的实现以及解释:
而在子类的init实现方法中我们可以看到做了如下的操作:
也就是打开一个选择器,说到这里我们想大家应该有点印象了,因为在我们之前将nio的时候我们知道在NIO中就是这个Secletor对管道进行管理的,也就是这个selector是一个类似于服务端和客户端管道大管家的角色,在这个secletor上注册了不同的事件,来相应。那么在这里我们知道是打开了这个secletor。哪可能你会问,哪我到这里换没有看到你的管道channel,selector等等的创建啊,好,其实我也是这么想的,别忘了在nioSocketAcceptor这个类的父类AbstractPollingIoAcceptor的构造方法中我们又去调用了AbstractPollingIoAcceptor的父类的构造方法,哪这个时候我们就去看看再哪里mina做了什么。
。。。不好意思在刚才说AbstractPollingIoAcceptor的构造函数的时候忘了说明一点就是在AbstractPollingIoAcceptor的构造函数中对NioProcessor进行了绑定,绑定有什么用呢,我们先看父类的构造函数中做了什么,再来说NioProcessor的用途。源码加解释:
是不是很扫兴,这都已经是第三个父类了,怎么还没有具体的实现,别灰心我们继续往下跟,其实这个时候我们应该去想想,mina为什么这样写代码,为什么要在父类的父类中取实现具体的操作,也许这也是一个设计模式或者模板,在这里我提出这个问题来咱们都去考虑考虑人家的代码为什么这样写.哪在这里我们还是接着来跟源码吧:
好了今天对mina服务端服务创建的一个过程做了一个大致简单的介绍,其实并不是很详细。我们目前暂时知道nioSocketAcceptor这个类的继承及实现接口的关心,以及知道在初始化的过程中每个类是负责干什么的。下节我们重点对这个的细节进行一个学习介绍。对细节学习介绍后,我们就开始对客户端请求到来的时候mina是如何处理这个请求的,我们知道在原生态的NIO中是通过selector这个大管家通关SelectionKey这个注册的时间来监听到是哪个通道发生的什么事件,然后我们根据发生的事件去做相应的操作,比如我们检测到通道现在可读,哪我们就从byteBuffer中将缓存的数据读出来。好了今天就到这里吧,我的脑袋现在也有点晕晕的,待我好好理理再跟大家细细道来。明天见,一会换有一个设计模式--适配器模式的学习和博客的编写。哎。。。革命尚未成功兄弟们还需努力啊。