---
# System prepended metadata

title: Netty AbstractBootstrap 及其子類介紹
tags: [netty, 軟體開發]

---

在[基礎介紹](https://hackmd.io/@Iv5IzxMYT4OfZ08k6tYFMw/SyLbPCfBa)中，我們把`AbstractBootstrap`歸類在核心元件之中，**負責的工作就是配置和啟動Netty 應用程式**，它的兩個子類別，`ServerBootstrap`用於建立伺服器、`Bootstrap`用於建立客戶端，是建立Netty 應用程式最基本的部分，因此有必要了解它們有哪些方法以及配置內容。

## AbstractBootstrap

首先要介紹的是`AbstractBootstrap`，它是`Bootstrap`和`ServerBootstrap`的父層抽象類，提供了一些共用屬性和方法，可以用來設定啟動應用程式所需的物件及參數，共同的方法如下：

- `group()`：指定用來處理IO 事件的`EventLoopGroup`。
- `channel()`：指定使用的`Channel`類型。
- `handler()`：指定在`Channel`的`EventLoop`上執行的`ChannelHandler`，通常使用`ChannelInitializer`初始化`ChannelPipeline`。
- `attr()`：設置`Channel`上的屬性。
- `option()`：設置`Channel`上的選項。

常用的屬性如下：

- `EventLoopGroup group;`
- `ChannelFactory<? extends C> channelFactory;`
- `SocketAddress localAddress;`
- `Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();`
- `Map<AttributeKey<?>, Object> attrs = new ConcurrentHashMap<AttributeKey<?>, Object>();`
- `ChannelHandler handler;`

在`AbstractBootstrap`的建構子中，定義了這些屬性的賦值。

```java
AbstractBootstrap(AbstractBootstrap<B, C> bootstrap) {
	group = bootstrap.group;
  channelFactory = bootstrap.channelFactory;
  handler = bootstrap.handler;
  localAddress = bootstrap.localAddress;
  synchronized (bootstrap.options) {
    options.putAll(bootstrap.options);
  }
  attrs.putAll(bootstrap.attrs);
}
```

而配置方法，如簡易實作中的`group()`、`channel()`和`handler()`，另外還有`option()`、`attr()`等，也都是向這些參數中賦值，並沒有其他處理邏輯。

### `Channel`

值得注意的是，在`AbstractBootstrap`中，關於`Channel`的屬性是`ChannelFactory`，而不是`Channel`。

這是因為`Channel`的配置方法有兩種，一種是簡易實作中的`channel()`，傳入一個`Channel.class`，另一種則是傳入`ChannelFactory`，具體細節可參考原始碼：

```java
public B channel(Class<? extends C> channelClass) {
  return channelFactory(new ReflectiveChannelFactory<C>(
      ObjectUtil.checkNotNull(channelClass, "channelClass")
  ));
}

@Deprecated
public B channelFactory(ChannelFactory<? extends C> channelFactory) {
  ObjectUtil.checkNotNull(channelFactory, "channelFactory");
  if (this.channelFactory != null) {
    throw new IllegalStateException("channelFactory set already");
  }

  this.channelFactory = channelFactory;
  return self();
}

@SuppressWarnings({ "unchecked", "deprecation" })
public B channelFactory(io.netty.channel.ChannelFactory<? extends C> channelFactory) {
  return channelFactory((ChannelFactory<C>) channelFactory);
}
```

從中可以看出，調用`channel()`傳入的`Channel.class`會被封裝在`ReflectiveChannelFactory`中，最終還是`ChannelFactory`屬性。這也表明了，Netty 在創建`Channel`時都是調用`ChannelFactory`。

### `attr()`

`attr()`方法用於設置`Channel`上的屬性，這些屬性可以用於存儲關於`Channel`的自定義信息。這些自定義的信息通常是與特定應用程式需求相關的，例如標記某個`Channel`的用途、額外的標記信息或其他自定義數據。

在`attr()`方法中，可以傳遞`AttributeKey`和相應的值。`AttributeKey`是用於標識屬性的鍵，它是一種類似於`Map`中的鍵的概念，用於唯一識別特定的屬性。通過`AttributeKey`，可以在`Channel`上設置和獲取各種自定義屬性。

使用`attr()`方法設置的屬性對於該`Channel`實例是獨立的，不會影響其他`Channel`實例。這意味著，開發人員可以根據自己的需求，將任意額外的信息與`Channel`相關聯，以滿足特定的業務需求。

### `option()`

`option()`方法用於設置`Channel`上的選項(options)，這些選項涉及到底層的TCP 協議層面的配置，可以影響到`Channel`的行為和性能。

透過`option()`方法，可以設置各種不同的選項，例如調整TCP 協議的超時時間、緩衝區大小、TCP 通訊的延遲和拥塞控制等。這些選項提供了一個方便的方式來優化和調整`Channel`的行為，以滿足不同應用場景的需求。

需要注意的是，設置不當的選項可能會影響系統的性能或行為。因此，在使用`option()`方法時，開發人員需要根據具體情況慎重考慮每個選項的影響，並根據實際需求進行適當的配置。

---

## Bootstrap

`Bootstrap` 是用於建立客戶端應用程式的類別，它具有一些重要的特性和方法，讓建立和設定客戶端應用程式變得更加容易和靈活。

除了在父類`AbstractBootstrap`中定義的通用屬性和方法外，`Bootstrap`還提供了設置遠端地址(`remoteAddress`)和地址解析器(`resolver`)的能力。遠端地址是客戶端應用程式要連接的伺服器地址，而地址解析器用於解析和轉換這些地址，尤其是當遠端地址不僅僅是 IP 地址時。這使得在建立客戶端時能夠更靈活地處理不同類型的遠端地址，例如主機名稱、域名等。

此外，`Bootstrap`也提供了設置TCP 選項和屬性的方法，例如`option()`和`attr()`，這些方法允許設置底層的TCP 參數，從而調整和優化客戶端和伺服器之間的通訊過程。

---

## ServerBootstrap

`ServerBootstrap`是用於建立伺服器應用程式的類別，它相對於`Bootstrap`還有一些額外的設定和功能，以支持伺服器的特殊需求。

與`Bootstrap`不同，`ServerBootstrap`在建立伺服器時需要設置兩個`EventLoopGroup`：Parent `EventLoopGroup`和Child `EventLoopGroup`。Parent `EventLoopGroup`負責接受傳入的連接，而Child `EventLoopGroup`則負責處理已接受連接的數據流量，以實現主從Reactor 多線程模型。

此外，因為伺服器應用程式需要監聽和接受客戶端的連接，`ServerBootstrap`也提供了設置本地地址(`localAddress`)的方法，以指定伺服器應用程式要監聽的地址和端口。

總體來說，`ServerBootstrap`提供了額外的設置和功能，以滿足建立和配置伺服器應用程式所需的特殊需求，使得建立高效和可靠的伺服器應用程式變得更為方便和彈性。

---

## 總結

總的來說，`AbstractBootstrap`是構建Netty 應用程式的重要組件之一，負責配置和啟動應用程式。其方法和屬性提供了豐富的功能，包括指定`EventLoopGroup`處理IO 事件、選擇`Channel`類型、設置`Channel`上的屬性和選項等，這些功能能夠靈活地定制和調整`Channel`的行為與特性。

`Bootstrap`作為`AbstractBootstrap`的子類之一，專注於建立客戶端應用程式，可設置**遠端地址**和**地址解析器**，同時允許設置TCP 選項和屬性，提供了靈活性和方便性。

而`ServerBootstrap`則是另一子類，專門用於建立伺服器應用程式。相較於`Bootstrap`，它需要設置兩個`EventLoopGroup`來處理傳入連接和數據流量，同時也提供了設置本地地址的方法。

深入了解這些類的方法和功能，對於建構高效、彈性且可靠的Netty 應用程式至關重要。這些組件為開發人員提供了靈活性，能根據具體的應用場景和需求進行定制，從而達到更好的性能和可擴展性。
