Netty服务端 Channel的创建
一、Netty 服务端启动过程
【1】创建服务端 Channel;
【2】初始化服务端 Channel;
【3】注册 Selector;
【4】端口绑定:我们分析源码的入口从端口绑定开始, ServerBootstrap 的 bind(int inetPort)方法,实际上是 AbstractBootstrap 的 bind(int inetPort) 方法。ServerBootstrap 继承了AbstractBootstrap。
二、分析服务端创建Channel的过程
【1】bind()【分析入口,端口绑定】在 bind() 方法中,有一个 doBind() 方法,处理端口绑定:
1 public ChannelFuture bind(SocketAddress localAddress) { 2 validate(); 3 if (localAddress == null) { 4 throw new NullPointerException("localAddress"); 5 } 6 return doBind(localAddress);// 实际绑定 7 }
【2】在 doBind()方法中,调用 initAndRegister来处理初始化和注册:
1 private ChannelFuture doBind(final SocketAddress localAddress) { 2 final ChannelFuture regFuture = initAndRegister();// 初始化与注册 3 // ... 4 }
【3】initAndRegister()【初始化并注册】进入 initAndRegister() 方法里面,发现是调用了 channelFactory(Channel工厂) 的 newChannel() 来创建 channel:
1 final ChannelFuture initAndRegister() { 2 Channel channel = null; 3 try { 4 channel = channelFactory.newChannel();// channelFactory创建Channel 5 init(channel); 6 } 7 //... 8 }
【4】newChannel()【创建服务端channel】进去 newChannel() 方法,就能看到,实际上是通过反射 Class.newInstance() 来创建 Channel 对象的:
public T newChannel() { try { return clazz.newInstance();// Channel工厂通过反射,来创建Channel } catch (Throwable t) { throw new ChannelException("Unable to create Channel from class " + clazz, t); } }
那么,这个class到底是啥呢,什么时候传递进来的?
【5】ChannelFactory的初始化:【接收服务端 Channel的 Class,通过反射生成 Channel】还记得之前我们的第一个Demo里面有一个 channel() 方法,我们传递了一个参数 - NioServerSocketChannel.class:
1 ServerBootstrap serverBoot = new ServerBootstrap(); 2 serverBoot.group(bossGroup,workGroup) 3 .channel(NioServerSocketChannel.class)// 设置服务端Channel 4 //... 5 );
进去 channel() 方法中:
1 public B channel(Class<? extends C> channelClass) { 2 if (channelClass == null) { 3 throw new NullPointerException("channelClass"); 4 } 5 return channelFactory(new ReflectiveChannelFactory<C> 6 (channelClass));// 传递class给ChannelFactory的构造方法 7 }
然后,我们进去 ChannelFactory 的构造方法里面:
1 public ReflectiveChannelFactory(Class<? extends T> clazz) { 2 if (clazz == null) { 3 throw new NullPointerException("clazz"); 4 } 5 this.clazz = clazz;// 接收传递进来的Channel的Class 6 } 7 @Override 8 public T newChannel() { 9 try { 10 return clazz.newInstance();// 通过Channel的Class反射生成Channel对象 11 } catch (Throwable t) { 12 throw new ChannelException("Unable to create Channel from class " + clazz, t); 13 } 14 }
到此,Channel的创建过程就出来了,一句话总结就是:通过我们在 ServerBootstrap的 channel(clazz) 方法里面设置的Class,通过 Java反射,Class.newInstance来生成最终的 Channel对象。