netty之bootstrap
转载自https://blog.csdn.net/zxhoo/article/details/17419229
Netty4学习笔记(2)-- Bootstrap
Netty4的代码比我想象的要复杂的多,不过Netty4很好的将这种复杂性隐藏了起来,暴露出来的,是一个相对容易使用的接口。Bootstrap就是Netty试图隐藏这种复杂性的一个例子。
bootstrap包
bootstrap包是Netty4代码里最简单的一个包,总共只有4个类:
Bootstrap继承结构
AbstractBootstrap是抽象类,有两个具体的实现,Bootstrap和ServerBootstrap:
Bootstrap例子
Netty4自带的例子里有一个EchoClient,看看它是如何使用Bootstrap启动一个客户端程序的:
public class EchoClient {
private final String host;
private final int port;
private final int firstMessageSize;
public EchoClient(String host, int port, int firstMessageSize) {
this.host = host;
this.port = port;
this.firstMessageSize = firstMessageSize;
}
public void run() throws Exception {
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(
//new LoggingHandler(LogLevel.INFO),
new EchoClientHandler(firstMessageSize));
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync();
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
// Shut down the event loop to terminate all threads.
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
// ...
}
}
Builder模式?
看上面的例子,Bootstrap的使用很像Builder模式,Bootstrap就是Builder,EventLoopGroup、Channel和Handler等是各种Part。稍有不同的是,准备好各种Part后,并不是直接build出一个Product来,而是直接通过connect()方法使用这个Product。
AbstractBootstrap
为了弄清楚Bootstrap如何工作,我们先从AbstractBootstrap入手:
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
private volatile EventLoopGroup group;
private volatile ChannelFactory<? extends C> channelFactory;
private volatile SocketAddress localAddress;
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
private volatile ChannelHandler handler;
// ...
}
可以看到,AbstractBootstrap这个抽象Builder一共需要有6个Part,如下图所示:
设置各个Part
AbstractBootstrap有一组方法用来设置各个Part,例如下面这些:
public B group(EventLoopGroup group)
public B channel(Class<? extends C> channelClass)
public B channelFactory(ChannelFactory<? extends C> channelFactory)
public B localAddress(SocketAddress localAddress)
public <T> B option(ChannelOption<T> option, T value)
public <T> B attr(AttributeKey<T> key, T value)
public B handler(ChannelHandler handler)
还有一组对应方法获得各个Part,如下:
final SocketAddress localAddress()
final ChannelFactory<? extends C> channelFactory()
final ChannelHandler handler()
public final EventLoopGroup group()
final Map<ChannelOption<?>, Object> options()
final Map<AttributeKey<?>, Object> attrs()
ChannelFactory
AbstractBootstrap通过ChannelFactory创建Channel实例,channel(channelClass)方法看起来好像是设置了一个Channel,但实际上只是设置了默认的ChannelFactory实现:
public B channel(Class<? extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new BootstrapChannelFactory<C>(channelClass));
}
默认的ChannelFactory实现使用反射创建Channel实例:
private static final class BootstrapChannelFactory<T extends Channel> implements ChannelFactory<T> {
private final Class<? extends T> clazz;
BootstrapChannelFactory(Class<? extends T> clazz) {
this.clazz = clazz;
}
@Override
public T newChannel() {
try {
return clazz.newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
}
Bootstrap.connect()
再来看Bootstrap类的connect()方法:
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {
if (remoteAddress == null) {
throw new NullPointerException("remoteAddress");
}
validate();
return doConnect(remoteAddress, localAddress);
}
connect()方法调用validate()方法看各个Part是否准备就绪,然后调用doConnect()方法:
private ChannelFuture doConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
}
final ChannelPromise promise = channel.newPromise();
if (regFuture.isDone()) {
doConnect0(regFuture, channel, remoteAddress, localAddress, promise);
} else {
regFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
doConnect0(regFuture, channel, remoteAddress, localAddress, promise);
}
});
}
return promise;
}
doConnect()方法首先调用了initAndRegister()方法,然后又调用了doConnect0()方法,方法调用示意图如下:
AbstractBootstrap.initAndRegister()
final ChannelFuture initAndRegister() {
final Channel channel = channelFactory().newChannel();
try {
init(channel);
} catch (Throwable t) {
channel.unsafe().closeForcibly();
return channel.newFailedFuture(t);
}
ChannelPromise regPromise = channel.newPromise();
group().register(channel, regPromise);
// ...
}
initAndRegister()方法用ChannelFactory创建了一个Channel的实例,然后调用init()方法初始化Channel,最后将Channel注册到EventLoopGroup上:
而Channel在实例化的时候已经自动关联了Pipeline,这点从AbstractChannel的构造函数可以看出:
protected AbstractChannel(Channel parent) {
this.parent = parent;
unsafe = newUnsafe();
pipeline = new DefaultChannelPipeline(this);
}
Bootstrap.init()方法
void init(Channel channel) throws Exception {
ChannelPipeline p = channel.pipeline();
p.addLast(handler());
// ...
}
Bootstrap.init()方法把Handler添加到了Pipeline的末尾,到这里,Channel就准备就绪了:
继续Bootstrap.doConnect()
initAndRegister()方法结束之后,doConnect()方法紧接着调用了doConnect0()方法,doConnect0()方法继而调用了Channel.connect()方法,这样Channel就接通服务器,可以收发消息了!
---------------------
作者:zxh0
来源:CSDN
原文:https://blog.csdn.net/zxhoo/article/details/17419229
版权声明:本文为博主原创文章,转载请附上博文链接!
netty之bootstrap的更多相关文章
- 【Netty】(5)源码 Bootstrap
[Netty]5 源码 Bootstrap 上一篇讲了AbstractBootstrap,为这篇做了个铺垫. 一.概述 Bootstrap 是 Netty 提供的一个便利的工厂类, 我们可以通过它来完 ...
- RPC框架motan: 通信框架netty之Netty4Client
上文已经初步探讨了如何实现一个具体的transport,本文就来讨论一个具体的transport,本文讨论netty4的的相关实现.老规矩,看看motan-transport的目录结构. 其中最重要的 ...
- Netty(RPC高性能之道)原理剖析
转载:http://blog.csdn.net/zhiguozhu/article/details/50517551 1,Netty简述 Netty 是一个基于 JAVA NIO 类库的异步通信框架, ...
- 新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析
1.引言 Netty 是一个广受欢迎的异步事件驱动的Java开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 本文基于 Netty 4.1 展开介绍相关理论模型,使用场景,基本组件 ...
- Netty断线重连
Netty断线重连 最近使用Netty开发一个中转服务,需要一直保持与Server端的连接,网络中断后需要可以自动重连,查询官网资料,实现方案很简单,核心思想是在channelUnregistered ...
- Netty心跳机制
一.概念介绍网络中的接收和发送数据都是使用操作系统中的SOCKET进行实现.但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题.可是如何判断这个套接字是否还可以使用呢?这个就需要在系统 ...
- netty ------------ 如果selector检测到一个channel可以读了
-----------------一个NioEventLoopGroup 的初始化的时候,会初始化一个 NioEventLoop数组,每个NioEventLoop在初始化的时候,会open一个sele ...
- 看 Netty 在 Dubbo 中如何应用
目录: dubbo 的 Consumer 消费者如何使用 Netty dubbo 的 Provider 提供者如何使用 Netty 总结 前言 众所周知,国内知名框架 Dubbo 底层使用的是 Net ...
- Java网络编程和NIO详解9:基于NIO的网络编程框架Netty
Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...
随机推荐
- openvswitch 监听端口变化
命令: ovsdb-client monitor Interface name,ofport,external_ids --format=json 运行效果: [root@ostack1 ~]# ov ...
- Cinder Volume 服务启动流程分析和周期性任务分析
1.cinder-volume服务的程序入口 #!/usr/bin/python2 # PBR Generated from u'console_scripts' import sys from ci ...
- Linux查看系统硬件信息命令汇总
对工作中,经常用的查看系统硬件命令的一个简单总结 1.查看磁盘类型(是否SSD盘)cat /sys/block/sda/queue/rotational注意:命令中的sba是你的磁盘名称,可以通过df ...
- 算法-搜索(5)m路搜索树
动态m路搜索树即系统运行时可以动态调整保持较高搜索效率的最多m路的搜索树.以3路搜索树为例说明其关键码排序关系: const int MaxValue=; template <class T ...
- 牛客网PAT练习场-到底买不买
题目地址:https://www.nowcoder.com/pat/6/problem/4065 题意:用数组统计好字符,最后进行相减,最后进行统计 /** * *作者:Ycute *时间:2019- ...
- Shell编程—图形化脚本
1创建文本菜单 1.1普通的文本菜单 $ cat menu1 #!/bin/bash # simple script menu function diskspace { clear df -k } f ...
- Angular 之我见
很久没有写过技术软文了,虽然 Angular 发布已有四年,得到了越来越多人的关注,但是仍然有很多人不分青红皂白的进行诋毁.我打算结合自己的经历从客观的角度说聊一聊我眼中的 Angular. 本人刚做 ...
- Htmlcss学习笔记2——选择器与常用样式
CSS引入类型 行内样式 内联样式 外部样式表 CSS选择器 基本选择器 复合选择器 伪类选择器 属性选择器 CSS字体样式 font-size font-family font-style font ...
- oracle坑。
char(2)的,后面的有一个空格.删不掉.在plsql里可以正常查.写死的sql在程序也可以正常查. 程序用占位符的形式,不能查出来.只能转成to_number select t.*,t.rowid ...
- AppStore SDK
ios审核被拒4.3 http://www.cocoachina.com/bbs/read.php?tid-1731757.html ios审核4.3被拒? 别担心 这几步让你的 App 顺利过审 h ...