okhttp建造者模式详解 - 实践

建造者模式的官方回答是

建造者模式(Builder Pattern) 是一种创建型设计模式,用于分步构建一个复杂对象,并将对象的构造过程与其表示分离,使得同样的构建过程可以创建不同的表示。

适用于:

  • 对象构造参数多(尤其是可选参数多);
  • 构造逻辑复杂;
  • 需要保证对象的不可变性(immutable)或线程安全

这个回答很模糊,我们来看看okhttp的源代码中定义从参数。

final Dispatcher dispatcher;
final @Nullable Proxy proxy;
final List protocols;
final List connectionSpecs;
final List interceptors;
final List networkInterceptors;
final EventListener.Factory eventListenerFactory;
final ProxySelector proxySelector;
final CookieJar cookieJar;
final @Nullable Cache cache;
final @Nullable InternalCache internalCache;
final SocketFactory socketFactory;
final SSLSocketFactory sslSocketFactory;
final CertificateChainCleaner certificateChainCleaner;
final HostnameVerifier hostnameVerifier;
final CertificatePinner certificatePinner;
final Authenticator proxyAuthenticator;
final Authenticator authenticator;
final ConnectionPool connectionPool;
final Dns dns;
final boolean followSslRedirects;
final boolean followRedirects;
final boolean retryOnConnectionFailure;
final int callTimeout;
final int connectTimeout;
final int readTimeout;
final int writeTimeout;
final int pingInterval;

符合对象构造参数多(尤其是可选参数多)特点,通过final的修饰参数,来保证线程安全。符合第三个特点。

public OkHttpClient() {
  this(new Builder());
}

OkHttpClient(Builder builder) {
  this.dispatcher = builder.dispatcher;
  this.proxy = builder.proxy;
  this.protocols = builder.protocols;
  this.connectionSpecs = builder.connectionSpecs;
  this.interceptors = Util.immutableList(builder.interceptors);
  this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
  this.eventListenerFactory = builder.eventListenerFactory;
  this.proxySelector = builder.proxySelector;
  this.cookieJar = builder.cookieJar;
  this.cache = builder.cache;
  this.internalCache = builder.internalCache;
  this.socketFactory = builder.socketFactory;

  boolean isTLS = false;
  for (ConnectionSpec spec : connectionSpecs) {
    isTLS = isTLS || spec.isTls();
  }

  if (builder.sslSocketFactory != null || !isTLS) {
    this.sslSocketFactory = builder.sslSocketFactory;
    this.certificateChainCleaner = builder.certificateChainCleaner;
  } else {
    X509TrustManager trustManager = Util.platformTrustManager();
    this.sslSocketFactory = newSslSocketFactory(trustManager);
    this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
  }

  if (sslSocketFactory != null) {
    Platform.get().configureSslSocketFactory(sslSocketFactory);
  }

  this.hostnameVerifier = builder.hostnameVerifier;
  this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
      certificateChainCleaner);
  this.proxyAuthenticator = builder.proxyAuthenticator;
  this.authenticator = builder.authenticator;
  this.connectionPool = builder.connectionPool;
  this.dns = builder.dns;
  this.followSslRedirects = builder.followSslRedirects;
  this.followRedirects = builder.followRedirects;
  this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
  this.callTimeout = builder.callTimeout;
  this.connectTimeout = builder.connectTimeout;
  this.readTimeout = builder.readTimeout;
  this.writeTimeout = builder.writeTimeout;
  this.pingInterval = builder.pingInterval;

  if (interceptors.contains(null)) {
    throw new IllegalStateException("Null interceptor: " + interceptors);
  }
  if (networkInterceptors.contains(null)) {
    throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
  }
}

构造逻辑确实很复杂。

下面我们来看看是怎么构造

我们常见的构造方式是

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .addInterceptor(new LoggingInterceptor())
        .retryOnConnectionFailure(true)
        .build()

先看connectTimeout 

public Builder connectTimeout(long timeout, TimeUnit unit) {
  connectTimeout = checkDuration("timeout", timeout, unit);
  return this;
}

原来每次设置参数都会返回当前build对象的this指针,当前对象像个链条传个下一个设置参数的函数。

最后看build

public OkHttpClient build() {
  return new OkHttpClient(this);
}

这里的this对象的类型是Builder,然后把Builder对象传递给OkHttpClient进行构建。

posted @ 2025-12-17 17:02  gccbuaa  阅读(36)  评论(0)    收藏  举报