netty 设计模式

"netty 设计模式"

Posted by tablesheep on

工厂模式

ChannelFactory

在使用 Netty 时都会设置 BootstrapChannel 类型

1
2
3
4
5
//Server
new ServerBootstrap().channel(NioServerSocketChannel.class);

//Client
new Bootstrap().channel(NioSocketChannel.class);

设置Channel的类型其实是创建了一个对应泛型的ReflectiveChannelFactory

1
2
3
4
5
6
//AbstractBootstrap.java
public B channel(Class<? extends C> channelClass) {
    return channelFactory(new ReflectiveChannelFactory<C>(
            ObjectUtil.checkNotNull(channelClass, "channelClass")
    ));
}

ReflectiveChannelFactory就是一个用反射创建对应Channel类型的工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * A {@link ChannelFactory} that instantiates a new {@link Channel} by invoking its default constructor reflectively.
 */
public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {

    private final Constructor<? extends T> constructor;

    public ReflectiveChannelFactory(Class<? extends T> clazz) {
        ObjectUtil.checkNotNull(clazz, "clazz");
        try {
            this.constructor = clazz.getConstructor();
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Class " + StringUtil.simpleClassName(clazz) +
                    " does not have a public non-arg constructor", e);
        }
    }

    @Override
    public T newChannel() {
        try {
            return constructor.newInstance();
        } catch (Throwable t) {
            throw new ChannelException("Unable to create Channel from class " + constructor.getDeclaringClass(), t);
        }
    }
......
}

EventExecutorChooserFactory

EventLoopGroup创建EventExecutorChooser时使用了工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {
......

    //根据数量创建不同的EventExecutorChooser
    @Override
    public EventExecutorChooser newChooser(EventExecutor[] executors) {
        if (isPowerOfTwo(executors.length)) {
            return new PowerOfTwoEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }
    ......
}

模板模式

AbstractBootstrap#init(Channel channel)

在客户端调用connect()方法或者服务端调用bind()方法时,会创建Channel并进行初始化操作。

1
2
3
4
5
6
7
8
9
//AbstractBootstrap#initAndRegister()
final ChannelFuture initAndRegister() {
    Channel channel = null;
    try {
        channel = channelFactory.newChannel();
        #init方法是个抽象方法具体的实现在Bootstrap或ServerBootstrap中
        init(channel);
    } ......
}

MultithreadEventExecutorGroup#newChild(Executor executor, Object… args)

Netty 有不同的EventLoopGroupNioEventLoopGroupEpollEventLoopGroupKQueueEventLoopGroup),这些EventLoopGroup都继承了MultithreadEventExecutorGroup,而在MultithreadEventExecutorGroup的构造方法中,通过 newChild(Executor executor, Object... args)创建实际的EventExecutor,而这个方法是个抽象方法,具体实现在上述的子类中会创建对应的EventLoopNioEventLoopEpollEventLoopKQueueEventLoop)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//MultithreadEventExecutorGroup
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
                                        EventExecutorChooserFactory chooserFactory, Object... args) {
    checkPositive(nThreads, "nThreads");

    if (executor == null) {
        executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
    }

    children = new EventExecutor[nThreads];

    for (int i = 0; i < nThreads; i ++) {
        boolean success = false;
        try {
            children[i] = newChild(executor, args);
            success = true;
        }......
    }

......
}

protected abstract EventExecutor newChild(Executor executor, Object... args) throws Exception;

单例模式

DefaultEventExecutorChooserFactory

1
2
3
4
5
6
7
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {

    public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();

    private DefaultEventExecutorChooserFactory() { }
    ......
}

Builder 模式

1
2
3
4
5
6
7
8
9
10
11
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.SO_BACKLOG, 128)
        .childOption(ChannelOption.SO_KEEPALIVE, true)
        .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new ServerHandler());
            }
        });

未完待续…