Netty进阶学习(三):Netty#doBind()的理解
背景
- 学习源码写作方式。
- 学习源码的考虑方式。
- 理解源码做了什么。
过程
- 从Server端绑定端口bind()入口。
说明
- 对参数进行验证,然后调用doBind()方法,并对方法需要的参数进行验证。
- 验证了什么?group(线程池实例是否有),channelFactory(通道工厂实例是否有),需要绑定的端口号是否有?
能够学到什么?
a) 在高层代码逻辑块里,应该是一句话的写作方式。validate()方法就是一句话的写作方式。doBind(final SocketAddress localAddress)也是一句话写作方式,对象工具类(ObjectUtil)也是典型的一句话写作方式。
b) 代码的健壮性。当前逻辑需要的参数,必须满足当前逻辑。必须满足。如果不满足大胆抛出异常,并说明原因。暗含之意:必须明确需求,需求不明,代码无法别写,代码根本无法做到健壮性。- doBind()方法
- doBind()方法
说明
- initAndRegister()初始化并注册。这个过程会实例化一个Channel对象。
- 这个异步操作的返回值类型是ChannelFuture,当执行initAndRegister()方法后,这个返回实例中的某些元素是没有或者有值的,比如可能它的属性isDone可能是true,也可能是false。也有可能在异步执行过程中发生了错误,那么cause属性就会有相应的错误描述。
- 一旦出现错误,则启动失败,没有必要继续往后执行了。这样的写作方式是,采用return截断代码。一般来说,这样的写作方式,可以称为优雅的写作方式。
- doBind()方法中的if(regFutre.isDone(){})的逻辑分析。
说明
- 判断异步执行结果成功完成。channel.newPromis()是为了获取下个函数需要的参数。调用doBind0()去完成端口绑定。
- 因为是多线程编程,异步执行逻辑的结果,是可能有可能无的。而我们的后续逻辑是依赖这个异步执行结果值的。于是就写了一个判断。
这里的ChannelPromis是ChannelFuture的子类。
- doBind()方法中的else{}的逻辑分析。
- 说明
- 如果没有异步操作没有完成的话,采用添加监听器的方式,完成doBind0()方法调用。
- PendingRegistrationPromise是ChannelFuture的子类。
- 由于添加了监听器,异步执行逻辑一定是执行完成了,但是我们并不知道它执行是成功的,还是失败的。所以这个判断是非常有必要的。
- 目的就是执行doBind0()方法。
- doBind()方法中的else{}的逻辑分析。
结论
- 一句话的写作方式。因为写代码,高层接口都是尽可能抽象编码骨架,其实,本质可以理解模板方法思路。或者理解为最小知识原则。越往底层,反而很难做到一句话的写作方式,但是必须要做到,定义更小的抽象函数,并且此函数只完成一件事。(技巧:拆大象的写作手法,并且牢记模板方法或者最小知识原则)
- 代码逻辑应该是严谨的,A一定是A,B一定是B。如果发现有不明确的参数,必须进行验证,一旦不满足条件,立即大胆抛出异常,并说明原因。这是需要学习的。在开发中,不停地确认需求,需求不明,代码是无法编写的,更别说健壮性了。
- 在多线程编程中,当后续逻辑依赖前面异步执行逻辑的结果的时候,判断是非常关键的,不能想当然,它一定是执行完成,或者它一定是未执行完成。
- 在多线程编程中,当添加监听器去接受异步操作结果的时候,可以判断它一定是执行完成了。这个执行完成又包含,执行成功完成,执行失败完成,所以依然需要判断。
还没有评论,来说两句吧...