Bootstrap 引导类
前面讲解了Netty整体架构以及类之间的关系,然后下面就先从框架的入口引导类(就是一个帮助类,存放了一些框架启动时必要的属性,例如ChannelFactory、ChannelPipeline、Map<String,Object> options)开始,看看是如何把这些类组装在一起的。
类关系
Bootstrap:封装了一些服务端和客户端引导类公共的逻辑,通过构造函数初始化参数
ServerBootstrap:继承了Bootstrap,组装了服务端所需要的相关的类 (创建的是需要连接的channel tcp/ip)
ClientBootstrap:继承了Bootstrap,组装了客户端所需要的相关的类 (创建的是需要连接的channel tcp/ip)
ConnectionlessBootstrap:继承了Bootstrap,(创建的是无需连接的channel udp/ip)
Bootstrap
该类提供了公共的数据结构,有创建Channel工厂、初始化了ChannelPipeline和ChannelPipelineFactory、存放了配置Channel参数的Map。
图-bootstrap0
两个构造方法,一个是无参的,一个是有ChannelFactory(创建Channel对象的工厂),如果在新建类时没有传入,那么一定需要调用setFactory方法传入(如果已经设置了channel factory那么就抛出IllegalStateException异常)
注意: 默认ChannelPipelineFactory 中的实现就是将pipeline中的ChannelHandler浅拷贝到新的DefaultChannelPipeline中,如果对于服务端接受多个Channel时,若ChannelHandler是有状态的话就会有线程安全问题(因为在没有同步情况下,多个线程操作同个内存资源),就必须要自己实现ChannelPipelineFactory接口来创建ChannelPipeline(这样每次获取pipeline都会重新new一个ChannelHandler)。
Map<String,Object> options 存放配置channel的信息,如果给子channel(有服务端接受客户端的channel)配置需要在key的名字用child前缀 例如:child.keepAlive
实现了ExternalResourceReleasable接口,表示该类支持释放外部资源,就是调用factory.releaseExternalResources()方法
ServerBootstrap
下面看看ServerBootstrap是如何绑定某个端口的,做了哪些操作
下面看bind操作,在某个ip和某个端口上进行监听客户端连接操作
Channel bind():会从options获取 key=localAddress,然后会调用bind(SocketAddress localAddress)方法
Channel bind(SocketAddress localAddress) 该方法最终会调用bindAsync(SocketAddress localAddress)方法,该方法是一个异步的,操作结果并不会马上获取到,当一有结果就会notify 添加的ChannelFutureListener,并唤醒阻塞等待结果的线程。 ChannelFututre中的awaitUninterruptibly方法就是会一直阻塞等待结果