mina学习总结

 

Mina使用起来多么简洁方便呀,就是不具备Java NIO的基础,只要了解了Mina常用的API,就可以灵活使用并完成应用开发。首先,看Mina在项目中所处的位置,如下图:

Mina处于中间层,它不关心底层网络数据如何传输,只负责接收底层数据,过滤并转换为Java对象提供给我们的应用程序,然后把应用程序响应值过滤并转换为底层识别的字节,提供给底层传输;

------总之:Mina是底层数据传输和用户应用程序交互的接口!

 

这个流程图不仅很直观的看出了Mina的工作流程,也涵盖了Mina的三个核心接口:IoService接口,IoFilter接口和IoHandler接口:

第一步. 创建服务对象(客户端或服务端)  ---IoService接口实现

第二步. 数据过滤(编码解码等)              ---IOFilter接口实现

第三步. 业务处理                                   ---IoHandler接口实现

  

   Mina的精髓是IOFilter,它可以进行日志记录,信息过滤,编码解码等操作,把数据接收发送从业务层独立出来。

   创建服务对象,则是把NIO繁琐的部分进行封装,提供简洁的接口。

   业务处理是我们最关心的部分,跟普通的应用程序没任何分别。

 

IoService接口

作用:IoService是创建服务的顶层接口,无论客户端还是服务端,都是从它继承实现的。

1 类结构

常用接口为:IoServiceIoAcceptorIoConnector

常用类为:NioSocketAcceptorNioSocketConnector

类图如下:

先提出两个问题:

  • 为什么有了IoService接口还要定义AbstractIoService抽象类?
  • AbstractIoService抽象类与IoAcceptor(IoConnector)有什么区别?

分析:

  • IoService接口声明了服务端的共有属性和行为;
  • IoAcceptor接口继承了IoService接口,并添加了服务端特有的接口属性及方法,比如bind()方法,成为典型的服务端接口;
  • IoConnector接口同样继承了IoService接口,并添加了客户端特有的接口属性及方法,比如connect()方法,成为典型的客户端接口;

       ---- IoServiceIoAcceptorIoConnector父接口,为什么不直接定义IoAcceptorIoConnector接口呢,因为          它们有共同的特点,比如共同属性,管理服务的方法等,所有IoService的出现是为了代码复用。

  • AbstractIoService实现了IoService中管理服务的方法,比如getFilterChainBuilder方法---获得过滤器链;

----为什么有了IoService接口还要定义AbstractIoService抽象类?一样为了代码的复用!AbstractIoService抽象类实现了服务端或客户端的共有的管理服务的方法,不需要让IoService接口的子类重复的实现这些方法;

  •  AbstractIoService抽象类继承了AbstractIoService抽象类并实现了IoAcceptor接口,成为了拥有管理服务端实现功能的服务端类;我们常用的NioSocketAcceptor就是它的子类;
  •   AbstractIoConnector抽象类继承了AbstractIoService抽象类并实现了IoConnector接口,成为了拥有管理客户端实现功能的客户端类;我们常用的NioSocketConnector就是它的子类;

----AbstractIoService抽象类与IoAcceptor(IoConnector)有什么区别?很清楚,AbstractIoService抽象类实现         的是共有的管理服务的方法,只有管理功能的一个类;而两个接口却是不同的两个服务角色----一个客户端,一个服         务端。

 

 

IoFilter接口

Mina最主要的工作就是把底层传输的字节码转换为Java对象,提供给应用程序;或者把应用程序返回的结果转换为字节码,交给底层传输。这些都是由IoFilter完成的,因此IoFilterMina的精髓所在。

Mina程序中,IoFilter是必不可少的;有了它,Mina的层次结构才异常清晰:

IoFilter   ----   消息过滤

IoHandler  ----   业务处理

    Filter,过滤器的意思。IoFilterI/O操作的过滤器。IoFilterServlet中的过滤器一样,主要用于拦截和过滤网络传输中I/O操作的各种消息。在Mina 的官方文档中已经提到了IoFilter 的作用:

1)记录事件的日志(Mina默认提供了LoggingFilter

2)测量系统性能

3)信息验证

4)过载控制

5)信息的转换(主要就是编码和解码)

6)和其他更多的信息

    IoService实例会绑定一个DefaultIoFilterChainBuilder ---- 过滤器链,我们把自定义的各种过滤器(IoFilter)自由的插放在这个过滤器链上了,类似于一种可插拔的功能!

2.2.1 类结构

常用接口为:IoFilterIoFilterChainBuilder

常用类为:IoFilterAdapterDefaultIoFilterChainBuilder

ProtocolCodecFilterLoggingFilter

类图如下:

 

同上面,先提出两个问题:

1. IoService中如何添加多个IoFilter

2. 如何自定义协议编解码器?

分析:

a. IoFilter2个实现类:IoFilterAdapter是个抽象的适配器类,我们可以根据需要扩展这个类,并且有选择的覆盖过滤器的方法;所有方法的默认把事件转发到下一个过滤器;查看源码如下:

public void sessionOpened(NextFilter nextFilter, IoSession session)throws Exception {

        nextFilter.sessionOpened(session);

  }

b .ReferenceCountingFilter封装了IoFilter实例,监看调用该filter的对象的个数,如果没有任何对象调用该IoFilter,就自动销毁IoFilter查看源码如下:

public class ReferenceCountingFilter implements IoFilter {

    private final IoFilter filter;

 

    private int count = 0;

 

    public ReferenceCountingFilter(IoFilter filter) {

        this.filter = filter;

    }

 

    public void init() throws Exception {

        // no-op, will init on-demand in pre-add if count == 0

    }

    public void destroy() throws Exception {

           } ……………

c. 实现IoFilterAdapter的类有多个,但是我们使用最多的就是

ProtocolCodecFilter----它是我们自定义编解码器的入口。

 

IoHandler接口

    IoHandlerMina实现其业务逻辑的顶级接口;它相当简单,你就理解它是根据事件触发的简单应用程序即可。

IoHandler中定义了7个方法,根据I/O事件来触发对应的方法:

import java.io.IOException;
public interface IoHandler {
    void sessionCreated(IoSession session) throws Exception;
    void sessionOpened(IoSession session) throws Exception;
    void sessionClosed(IoSession session) throws Exception;
    void sessionIdle(IoSession session, IdleStatus status) throws Exception;
    void exceptionCaught(IoSession session, Throwable cause) throws Exception;
    void messageReceived(IoSession session, Object message) throws Exception;
    void messageSent(IoSession session, Object message) throws Exception;
}
 

sessionCreated:当一个新的连接建立时,由I/O processor thread调用;

sessionOpened:当连接打开是调用;

messageReceived:当接收了一个消息时调用;

messageSent:当一个消息被(IoSession#write)发送出去后调用;

sessionIdle:当连接进入空闲状态时调用;

sessionClosed:当连接关闭时调用;

exceptionCaught:当实现IoHandler的类抛出异常时调用;

一般情况下,我们最关心的只有messageReceived方法,接收消息并处理,然后调用IoSessionwrite方法发送出消息!(注意:这里接收到的消息都是Java对象,在IoFilter中所有二进制数据都被解码啦!)

    一般情况下很少有人实现IoHandler接口,而是继承它的一个实现类IoHandlerAdapter,这样不用覆盖它的7个方法,只需要根据具体需求覆盖其中的几个方法就可以!

 

Iohandler7个方法其实是根据session4个状态值间变化来调用的:

l  Connected会话被创建并使用;

l  Idle会话在一段时间(可配置)内没有任何请求到达,进入空闲状态;

l  Closing会话将被关闭(剩余message将被强制flush);

l  Closed会话被关闭;

状态转换图如下:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值