public B channelFactory(io.netty.channel.ChannelFactory<? extends C> channelFactory){ return channelFactory((ChannelFactory<C>) channelFactory); }
public B channelFactory(ChannelFactory<? extends C> channelFactory){ if (channelFactory == null) { thrownew NullPointerException("channelFactory"); } if (this.channelFactory != null) { thrownew IllegalStateException("channelFactory set already"); } this.channelFactory = channelFactory; // 设置 Channel 生成工厂实例即ReflectiveChannelFactory return (B) this; }
其中ReflectiveChannelFactory 类的继承关系
1 2 3
public class ReflectiveChannelFactory public interface ChannelFactory // io.netty.channel.ChannelFactory public interface ChannelFactory // io.netty.bootstrap.channelFactory
public ChannelFuture bind(){ public ChannelFuture bind(int inetPort)// 本文中调用的 public ChannelFuture bind(String inetHost, int inetPort) public ChannelFuture bind(InetAddress inetHost, int inetPort) public ChannelFuture bind(SocketAddress localAddress)
private ChannelFuture doBind(final SocketAddress localAddress){ final ChannelFuture regFuture = initAndRegister(); final Channel channel = regFuture.channel(); if (regFuture.cause() != null) { return regFuture; }
if (regFuture.isDone()) { // At this point we know that the registration was complete and successful. ChannelPromise promise = channel.newPromise(); doBind0(regFuture, channel, localAddress, promise); return promise; } else { // Registration future is almost always fulfilled already, but just in case it's not. final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel); regFuture.addListener(new ChannelFutureListener() { @Override publicvoidoperationComplete(ChannelFuture future)throws Exception { Throwable cause = future.cause(); if (cause != null) { // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an // IllegalStateException once we try to access the EventLoop of the Channel. promise.setFailure(cause); } else { // Registration was successful, so set the correct executor to use. // See https://github.com/netty/netty/issues/2586 promise.executor = channel.eventLoop(); } doBind0(regFuture, channel, localAddress, promise); } }); return promise; } }
final ChannelFuture regFuture = initAndRegister();
// initAndRegister 方法逻辑 final ChannelFuture initAndRegister(){ // 生成 NioServerSocketChannel 实例(之前channel 方法设定的) final Channel channel = channelFactory().newChannel(); // 1 try { init(channel); // 2 } catch (Throwable t) { channel.unsafe().closeForcibly(); // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor returnnew DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t); }
ChannelFuture regFuture = group().register(channel); if (regFuture.cause() != null) { if (channel.isRegistered()) { channel.close(); } else { channel.unsafe().closeForcibly(); } }
// If we are here and the promise is not failed, it's one of the following cases: // 1) If we attempted registration from the event loop, the registration has been completed at this point. // i.e. It's safe to attempt bind() or connect() now because the channel has been registered. // 2) If we attempted registration from the other thread, the registration request has been successfully // added to the event loop's task queue for later execution. // i.e. It's safe to attempt bind() or connect() now: // because bind() or connect() will be executed *after* the scheduled registration task is executed // because register(), bind(), and connect() are all bound to the same thread.
publicstaticvoidtestMediator(){ CharMediatorImpl mediator = new CharMediatorImpl(); UserImpl walter = new UserImpl(mediator, "walter"); mediator.addUser(walter); mediator.addUser(new UserImpl(mediator, "ym")); mediator.addUser(new UserImpl(mediator, "cj")); mediator.addUser(new UserImpl(mediator, "test"));
walter.sendMessage("Hello World"); }
解释结果
1 2 3 4
2015-09-0808:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl sendMessage:16 -> User walter send msg Hello World!!! 2015-09-0808:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl receive:23 -> User ym receive msg Hello World!!! 2015-09-0808:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl receive:23 -> User cj receive msg Hello World!!! 2015-09-0808:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl receive:23 -> User test receive msg Hello World!!!
// template method, order is fioxed // final so subclasses can not override it publicfinalvoidbuildHouse(){ buildFoudation(); buildPillers(); buildWalls(); buildWindows(); } publicvoidbuildWindows(){ logger.info("HouseTemplate build windows!!!"); }
@Override publicvoidbuildWalls(){ // TODO Auto-generated method stub logger.info("build house with glass walls!!!"); }
@Override publicvoidbuildPillers(){ // TODO Auto-generated method stub logger.info("build house with glass pills!!!"); } }
Test Method
现在开始测试我们刚刚实现的模板方法模式 代码
1 2 3 4 5 6 7 8
publicstaticvoidtestTemplateMethod(){ HouseTemplate house = new WoodenHouse(); house.buildHouse(); logger.info("================================");
house = new GlassHouse(); house.buildHouse(); }
输出
1 2 3 4 5 6 7 8 9
2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildFoudation:27 -> HouseTemplate build foudation!!! 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.WoodenHouse buildPillers:18 -> build house with wooden pills!!! 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.WoodenHouse buildWalls:12 -> build house with wooden walls!!! 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildWindows:19 -> HouseTemplate build windows!!! 2015-09-0722:43:28 INFO com.walterlife.dp.App testTemplateMethod:24 -> ================================ 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildFoudation:27 -> HouseTemplate build foudation!!! 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.GlassHouse buildPillers:18 -> build house with glass pills!!! 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.GlassHouse buildWalls:12 -> build house with glass walls!!! 2015-09-0722:43:28 INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildWindows:19 -> HouseTemplate build windows!!!