优质博文:IT-BLOG-CN
一、Netty 服务端启动过程
【1】创建服务端Channel
;
【2】初始化服务端Channel
;
【3】注册Selector
;
【4】端口绑定:我们分析源码的入口从端口绑定开始,ServerBootstrap
的bind(int inetPort)
方法,实际上是AbstractBootstrap
的bind(int inetPort)
方法。ServerBootstrap
继承了AbstractBootstrap
。
二、分析服务端创建Channel的过程
【1】bind()
【分析入口,端口绑定】在bind()
方法中,有一个doBind()
方法,处理端口绑定:
public ChannelFuture bind(SocketAddress localAddress) {validate();if (localAddress == null) {throw new NullPointerException("localAddress");}return doBind(localAddress);// 实际绑定
}
【2】在doBind()
方法中,调用initAndRegister
来处理初始化和注册:
private ChannelFuture doBind(final SocketAddress localAddress) {final ChannelFuture regFuture = initAndRegister();// 初始化与注册// ...
}
【3】initAndRegister()
【初始化并注册】进入initAndRegister()
方法里面,发现是调用了channelFactory
(Channel
工厂) 的newChannel()
来创建channel
:
final ChannelFuture initAndRegister() {Channel channel = null;try {channel = channelFactory.newChannel();// channelFactory创建Channelinit(channel);}//...
}
【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
:
ServerBootstrap serverBoot = new ServerBootstrap();
serverBoot.group(bossGroup,workGroup).channel(NioServerSocketChannel.class)// 设置服务端Channel//...
);
进去channel()
方法中:
public B channel(Class<? extends C> channelClass) {if (channelClass == null) {throw new NullPointerException("channelClass");}return channelFactory(new ReflectiveChannelFactory<C>(channelClass));// 传递class给ChannelFactory的构造方法
}
然后,我们进去ChannelFactory
的构造方法里面:
public ReflectiveChannelFactory(Class<? extends T> clazz) {if (clazz == null) {throw new NullPointerException("clazz");}this.clazz = clazz;// 接收传递进来的Channel的Class
}
@Override
public T newChannel() {try {return clazz.newInstance();// 通过Channel的Class反射生成Channel对象} catch (Throwable t) {throw new ChannelException("Unable to create Channel from class " + clazz, t);}
}
到此,Channel
的创建过程就出来了,一句话总结就是:通过我们在ServerBootstrap
的channel(clazz)
方法里面设置的Class
,通过Java
反射,Class.newInstance
来生成最终的Channel
对象。