MIna框架I/O Filter Chain层设计

简介:
I/O Filter Chain层是介于I/O Service层与I/O Handler层之间的一层,从它的命名上可以看出,这个层可以根据实际应用的需要,设置一组IoFilter来对I/O Service层与I/O Handler层之间传输数据进行过滤,任何需要在这两层之间进行处理的逻辑都可以放到IoFilter中。
我们看一下IoFilter的抽象层次设计,如图所示:

通过上述类图可见,要实现一个自定义的IoFilter,一般是直接实现IoFilterAdapter类。同时,Mina也给出了几类常用的开发IoFilter的实现类,如下所示:

  • LoggingFilter记录所有事件和请求
  • ProtocolCodecFilter将到来的ByteBuffer转换成消息对象(POJO)
  • CompressionFilter压缩数据
  • SSLFilter增加SSL – TLS – StartTLS支持

想要实现一个自定义的IoFilter实现类,只需要基于上述给出的几个实现类即可。
如果想要实现自己的IoFilter,可以参考如下例子:

1 public class MyFilter extends IoFilterAdapter {
2 @Override
3 public void sessionOpened(NextFilter nextFilter, IoSession session) throwsException {
4 // Some logic here...
5 nextFilter.sessionOpened(session);
6 // Some other logic here...
7 }
8 }

下面通过一个例子来说明,如何使用IoFilter的实现类。

ProtocolCodecFilter
下面是Mina自带的例子,使用了ProtocolCodecFilter类:

01 package org.apache.mina.example.gettingstarted.timeserver;
02
03 import java.io.IOException;
04 import java.net.InetSocketAddress;
05 import java.nio.charset.Charset;
06
07 import org.apache.mina.core.service.IoAcceptor;
08 import org.apache.mina.core.session.IdleStatus;
09 import org.apache.mina.filter.codec.ProtocolCodecFilter;
10 import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
11 import org.apache.mina.filter.logging.LoggingFilter;
12 import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
13
14 public class MinaTimeServer {
15 /**
16 * We will use a port above 1024 to be able to launch the server with a
17 * standard user
18 */
19 private static final int PORT = 9123;
20
21 /**
22 * The server implementation. It's based on TCP, and uses a logging filter
23 * plus a text line decoder.
24 */
25 public static void main(String[] args) throws IOException {
26 // Create the acceptor
27 IoAcceptor acceptor = new NioSocketAcceptor();
28
29 // Add two filters : a logger and a codec
30 acceptor.getFilterChain().addLast("logger", new LoggingFilter());
31 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));
32
33 // Attach the business logic to the server
34 acceptor.setHandler(new TimeServerHandler());
35
36 // Configurate the buffer size and the iddle time
37 acceptor.getSessionConfig().setReadBufferSize(2048);
38 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
39
40 // And bind !
41 acceptor.bind(new InetSocketAddress(PORT));
42 }
43 }

上面设置了两个IoFilter,关键是看如果基于文本行的消息,使用一个ProtocolCodecFilter包裹了一TextLineCodecFactory类的实例,使用起来非常容易。
构造一个ProtocolCodecFilter实例,需要实现一个ProtocolCodecFactory实例,一个ProtocolCodecFactory包含了对消息进行编解码(Codec)的逻辑,这样实现的好处是将编解码的逻辑和IoFilter解耦合。下面看一下类图:

LoggingFilter
如果需要记录通信过程中的事件以及请求,则可以直接使用LoggingFilter类,使用方法可以参考上面的例子。

CompressionFilter
CompressionFilter是与压缩/解压缩数据相关的IoFilter,我们可以看一下该类的构造方法,如下所示:

01 /**
02 * Creates a new instance which compresses outboud data and decompresses
03 * inbound data with default compression level.
04 */
05 public CompressionFilter() {
06 this(true, true, COMPRESSION_DEFAULT);
07 }
08
09 /**
10 * Creates a new instance which compresses outboud data and decompresses
11 * inbound data with the specified <tt>compressionLevel</tt>.
12 *
13 * @param compressionLevel the level of compression to be used. Must
14 */
15 public CompressionFilter(final int compressionLevel) {
16 this(true, true, compressionLevel);
17 }
18
19 /**
20 * Creates a new instance.
21 *
22 * @param compressInbound <tt>true</tt> if data read is to be decompressed
23 * @param compressOutbound <tt>true</tt> if data written is to be compressed
24 * @param compressionLevel the level of compression to be used. Must
25 */
26 public CompressionFilter(final boolean compressInbound, final booleancompressOutbound, final int compressionLevel) {
27 this.compressionLevel = compressionLevel;
28 this.compressInbound = compressInbound;
29 this.compressOutbound = compressOutbound;
30 }

基本上就构造方法参数中指定的3个参数与压缩/解压缩相关:

  • compressionLevel
  • compressInbound
  • compressOutbound

使用的时候也比较简单,只需要创建一个CompressionFilter实例,加入到Filter Chain中即可。

DefaultIoFilterChainBuilder
Mina自带的DefaultIoFilterChainBuilder可以非常容易就可以构建一个Filter Chain,默认在创建IoAcceptor和IoConnector的时候,可以直接通过他们获取到一个DefaultIoFilterChainBuilder的实例,然后调用add*方法设置IoFilter链,如下面代码中示例:

1 IoAcceptor acceptor = new NioSocketAcceptor();
2
3 // Add two filters : a logger and a codec
4 acceptor.getFilterChain().addLast("logger", new LoggingFilter());
5 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));

下面看一下来自Mina官网的表格,Mina框架也给出了一些典型的IoFilter的实现,引用如下所示:


Filter class Description
Blacklist BlacklistFilter Blocks connections from blacklisted remote addresses
Buffered Write BufferedWriteFilter Buffers outgoing requests like the BufferedOutputStream does
Compression CompressionFilter
ConnectionThrottle ConnectionThrottleFilter
ErrorGenerating ErrorGeneratingFilter
Executor ExecutorFilter
FileRegionWrite FileRegionWriteFilter
KeepAlive KeepAliveFilter
Logging LoggingFilter Logs event messages, like MessageReceived, MessageSent, SessionOpened, …
MDC Injection MdcInjectionFilter Inject key IoSession properties into the MDC
Noop NoopFilter A filter that does nothing. Useful for tests.
Profiler ProfilerTimerFilter Profile event messages, like MessageReceived, MessageSent, SessionOpened, …
ProtocolCodec ProtocolCodecFilter A filter in charge of encoding and decoding messages
Proxy ProxyFilter
Reference counting ReferenceCountingFilter Keeps track of the number of usages of this filter
RequestResponse RequestResponseFilter
SessionAttributeInitializing SessionAttributeInitializingFilter
StreamWrite StreamWriteFilter
SslFilter SslFilter
WriteRequest WriteRequestFilter

目录
相关文章
|
编解码 Linux Android开发
安卓投屏神器 Scrcpy 安装与使用(支持 Mac、Windows、Linux)
安卓投屏神器 Scrcpy 安装与使用(支持 Mac、Windows、Linux)
53608 1
|
1月前
|
人工智能 小程序 程序员
Skill详解(2万字详细教程),Skills是什么,如何安装并使用Skills
AI时代必备技能!Skills(智能体技能)是Anthropic提出的可复用能力包,以文件夹形式封装指令、脚本与资源,实现“按需加载”,大幅节省Token。它让大模型从聊天工具升级为专业助手——非技术岗也能零代码快速上手,真正实现人人可用、岗岗必备。
6735 12
Skill详解(2万字详细教程),Skills是什么,如何安装并使用Skills
|
存储 Java Nacos
学成在线笔记+踩坑(4)——【媒资管理模块】上传图片,Nacos+Gateway+MinIO
媒资管理模块简介、MinIO构建分布式文件系统、MinIO数据恢复演示 、【媒资模块】上传图片
学成在线笔记+踩坑(4)——【媒资管理模块】上传图片,Nacos+Gateway+MinIO
|
存储 运维 应用服务中间件
【实用经验分享】JumpServer部署教训:避免自信陷阱,谨慎行事
本文是关于使用JumpServer作为堡垒机进行服务器运维管理的经验分享。作者讲述了选择JumpServer的背景、从2.5.0版本升级到2.9.2版本的过程,以及在大厦断电后重新部署服务时遇到的挑战。文章详细描述了解决nginx和https配置问题的方法,并强调了在部署过程中保持谨慎、利用官方文档以及社区支持的重要性。最后,作者提到了数据迁移的问题,指出虽然旧数据无法直接融合到新版本中,但通过手动重新添加,能够顺利完成数据迁移。
1193 2
【实用经验分享】JumpServer部署教训:避免自信陷阱,谨慎行事
|
Web App开发 前端开发 JavaScript
JavaScript Web Full Stack 全栈开发者路线及内容推荐
本文详细介绍了一条全面的JavaScript全栈开发者学习路径,涵盖基础知识、前端和后端开发、数据库与API、MERN Stack与React Native、工程化与部署、安全与测试、未来趋势等方面。推荐了HTML5、CSS3、JavaScript(ES6+)、Node.js、React.js、Vue.js、Svelte、Tailwind CSS、Web Components等关键技术,并提供了丰富的书籍、博主和在线资源。此外,还回顾了JavaScript的历史,并推荐了多个活跃的社区和平台,帮助开发者紧跟技术前沿。
|
资源调度 前端开发 JavaScript
Next.js 项目最佳实践
万字干货,超详细教程带你了解如何构建一个可扩展的高质量 Next.js 项目。Node.js 工程师 & 前端工程师进阶必备技能
2185 0
Next.js 项目最佳实践
|
网络协议 Java Apache
Apache MINA (3) NioSocketAcceptor初始化
上一篇博客Apache MINA (2) Hello World! 以一个例子实现了mina客户端和服务端的通讯,现在通过源码来了解建立连接和通讯的过程(基于tcp/ip的实现)。 服务端通过创建一个NioSocketAcceptor来接受请求,客户端通过创建NioSocketConnector来
2497 74
|
Arthas Java 测试技术
Arthas可以对线上jar中的代码进行断点查看
Arthas可以对线上jar中的代码进行断点查看
5197 1
|
API 开发工具 Android开发
Android 8.1/9.0 一份能用的录音机源码
Android 8.1/9.0 一份能用的录音机源码
714 0
Android 8.1/9.0 一份能用的录音机源码
|
XML 前端开发 Java
Spring概述
Spring概述
435 0
Spring概述