82

Jetty源码剖析系列(6) - Connector与ServerSocket

 6 years ago
source link: http://ericcenblog.com/2018/02/22/jettyyuan-ma-pou-xi-xi-lie-6-connectoryu-serversocket/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本文主要从源代码的角度来分析Jetty的Connector如何通过ServerSocket来绑定和监听网络地址和端口的过程。 Jetty的Connector实现类是ServerConnector,循例从它的doStart()方法开始(至于是如何到达这个方法,请移步本系列的前几篇): 它的doStart方法先调用父类AbstractNetworkConnector的doStart方法: 在父类的doStart方法里面会调用子类实现的open方法,此处是ServerConnector的open方法: 到这里已经可以看到Jetty的Connector与Java NIO的关系了,将会调用openAcceptChannel方法来构建一个NIO的ServerSocketChannel: 从上图的代码我们可以看到,Jetty默认用Java NIO来实现了它的网络框架,另外一点就是,如果你用java来实现一套网络框架,无非就是BIO和NIO两种,返朴归真。 先常规调用ServerSocketChannel的静态方法open方法来打开一个ServerSocketChannel: 因为Java的NIO是基于Selector来实现的,所以在这里会通过SelectorProvider类的静态方法provider来加载Selector的实现类: 它先尝试从System Property里加载Selector的实现类并实例化: 如果没有的话,就尝试通过SPI的方式来加载Selector的实现类并实例化: 如果还是没有的话,就用Default的Selector,这个是根据底层操作系统来决定,比如,在Windows系统里将会是WindowsSelectorProvider这个类: WindowsSelectorProvider继承于SelectorProviderImpl这个抽象类, 它的openServerSocketChannel方法将会返回一个新建出来的ServerSocketChannelImpl对象: 到此我们再回过头看ServerConnector的openAcceptChannel方法, 上图通过ServerSocketChannel.open()方法拿到的就是一个ServerSocketChannelImpl实例对象, 我们接着往下看, 如果你没在启动参数里加--host参数,那它就会去指定所谓的全零地址: 那这个所谓的anyLocalAddress又是怎么来的呢? 这里impl是InetAddressImpl,它是在加载InetAddress类的时候,通过它的类静态块初始化的: 而InetAddressImplFactory会通过一个本地方法isIPv6Supported来判断底层操作系统是否支持IPv6,来加载InetAddressImpl的实现类: 在我的windows系统里,是支持IPv6的,所以返回的InetAddressImpl应该是Inet6AddressImpl对象,再来看它的anyLocalAddress方法:

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK