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

目录
相关文章
|
4月前
|
设计模式 Java 测试技术
分层设计:Service 层真的需要实现接口吗?
【8月更文挑战第4天】在软件开发领域,分层设计是一种广泛应用且高效的设计模式,它通过将系统划分为不同的逻辑层(如表现层、服务层、数据访问层等),来提高代码的可维护性、可扩展性和可测试性。其中,Service层作为业务逻辑处理的核心,其设计尤为重要。那么,Service层是否真的需要实现接口呢?这个问题值得我们深入探讨。
174 8
|
5月前
业务系统架构实践问题之如何在biz层复用domain层的服务如何解决
业务系统架构实践问题之如何在biz层复用domain层的服务如何解决
|
5月前
业务系统架构实践问题之代码应该主要放在biz层还是domain层
业务系统架构实践问题之代码应该主要放在biz层还是domain层
|
XML Java 应用服务中间件
Filter 过滤器--基本原理--Filter 过滤器生命周期--过滤器链--注意事项和细节--全部应用实例--综合代码示例
Filter 过滤器--基本原理--Filter 过滤器生命周期--过滤器链--注意事项和细节--全部应用实例--综合代码示例
177 0
|
7月前
|
消息中间件 Dubbo Java
Simple RPC - 01 框架原理及总体架构初探
Simple RPC - 01 框架原理及总体架构初探
88 0
Filter过滤器概念及生命周期
Filter过滤器概念及生命周期
159 0
|
前端开发 JavaScript 数据处理
mvc深刻理解,logic,service,model层的作用
mvc深刻理解,logic,service,model层的作用
386 0
|
开发者
OR-Mapping 设计改进(数据层结构调整) | 学习笔记
简介:快速学习 OR-Mapping 设计改进(数据层结构调整)
TP5.1门面类facade钩子behavior工具类,逻辑层service
TP5.1门面类facade钩子behavior工具类,逻辑层service
339 0
TP5.1门面类facade钩子behavior工具类,逻辑层service