欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

AsyncHttpClient?RequestFilter請(qǐng)求篩選源碼解讀

 更新時(shí)間:2023年12月13日 09:57:13   作者:codecraft  
這篇文章主要為大家介紹了AsyncHttpClient?RequestFilter請(qǐng)求篩選源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下AsyncHttpClient的RequestFilter

RequestFilter

org/asynchttpclient/filter/RequestFilter.java

/**
 * A Filter interface that gets invoked before making an actual request.
 */
public interface RequestFilter {
  /**
   * An {@link org.asynchttpclient.AsyncHttpClient} will invoke {@link RequestFilter#filter} and will use the
   * returned {@link FilterContext#getRequest()} and {@link FilterContext#getAsyncHandler()} to continue the request
   * processing.
   *
   * @param ctx a {@link FilterContext}
   * @param <T> the handler result type
   * @return {@link FilterContext}. The {@link FilterContext} instance may not the same as the original one.
   * @throws FilterException to interrupt the filter processing.
   */
  <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException;
}
RequestFilter定義了filter方法

ThrottleRequestFilter

org/asynchttpclient/filter/ThrottleRequestFilter.java

/**
 * A {@link org.asynchttpclient.filter.RequestFilter} throttles requests and block when the number of permits is reached,
 * waiting for the response to arrives before executing the next request.
 */
public class ThrottleRequestFilter implements RequestFilter {
  private static final Logger logger = LoggerFactory.getLogger(ThrottleRequestFilter.class);
  private final Semaphore available;
  private final int maxWait;
  public ThrottleRequestFilter(int maxConnections) {
    this(maxConnections, Integer.MAX_VALUE);
  }
  public ThrottleRequestFilter(int maxConnections, int maxWait) {
    this(maxConnections, maxWait, false);
  }
  public ThrottleRequestFilter(int maxConnections, int maxWait, boolean fair) {
    this.maxWait = maxWait;
    available = new Semaphore(maxConnections, fair);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException {
    try {
      if (logger.isDebugEnabled()) {
        logger.debug("Current Throttling Status {}", available.availablePermits());
      }
      if (!available.tryAcquire(maxWait, TimeUnit.MILLISECONDS)) {
        throw new FilterException(String.format("No slot available for processing Request %s with AsyncHandler %s",
                ctx.getRequest(), ctx.getAsyncHandler()));
      }
    } catch (InterruptedException e) {
      throw new FilterException(String.format("Interrupted Request %s with AsyncHandler %s",
              ctx.getRequest(), ctx.getAsyncHandler()));
    }
    return new FilterContext.FilterContextBuilder<>(ctx)
            .asyncHandler(ReleasePermitOnComplete.wrap(ctx.getAsyncHandler(), available))
            .build();
  }
}
ThrottleRequestFilter實(shí)現(xiàn)了RequestFilter接口,它使用Semaphore來(lái)對(duì)request進(jìn)行限流,限流不通過(guò)拋出FilterException,若通過(guò)則通過(guò)ReleasePermitOnComplete.wrap(ctx.getAsyncHandler(), available)包裝一下asyncHandler以釋放信號(hào)量ReleasePermitOnComplete

ReleasePermitOnComplete

org/asynchttpclient/filter/ReleasePermitOnComplete.java

/**
 * Wrapper for {@link AsyncHandler}s to release a permit on {@link AsyncHandler#onCompleted()}. This is done via a dynamic proxy to preserve all interfaces of the wrapped handler.
 */
public class ReleasePermitOnComplete {
  /**
   * Wrap handler to release the permit of the semaphore on {@link AsyncHandler#onCompleted()}.
   *
   * @param handler   the handler to be wrapped
   * @param available the Semaphore to be released when the wrapped handler is completed
   * @param <T>       the handler result type
   * @return the wrapped handler
   */
  @SuppressWarnings("unchecked")
  public static <T> AsyncHandler<T> wrap(final AsyncHandler<T> handler, final Semaphore available) {
    Class<?> handlerClass = handler.getClass();
    ClassLoader classLoader = handlerClass.getClassLoader();
    Class<?>[] interfaces = allInterfaces(handlerClass);
    return (AsyncHandler<T>) Proxy.newProxyInstance(classLoader, interfaces, (proxy, method, args) -> {
        try {
          return method.invoke(handler, args);
        } finally {
          switch (method.getName()) {
            case "onCompleted":
            case "onThrowable":
              available.release();
            default:
          }
        }
    });
  }
  //......
}
ReleasePermitOnComplete的wrap對(duì)原來(lái)的handler進(jìn)行代理,在finally里頭執(zhí)行available.release()

preProcessRequest

org/asynchttpclient/DefaultAsyncHttpClient.java

/**
   * Configure and execute the associated {@link RequestFilter}. This class
   * may decorate the {@link Request} and {@link AsyncHandler}
   *
   * @param fc {@link FilterContext}
   * @return {@link FilterContext}
   */
  private <T> FilterContext<T> preProcessRequest(FilterContext<T> fc) throws FilterException {
    for (RequestFilter asyncFilter : config.getRequestFilters()) {
      fc = asyncFilter.filter(fc);
      assertNotNull(fc, "filterContext");
    }
    Request request = fc.getRequest();
    if (fc.getAsyncHandler() instanceof ResumableAsyncHandler) {
      request = ResumableAsyncHandler.class.cast(fc.getAsyncHandler()).adjustRequestRange(request);
    }
    if (request.getRangeOffset() != 0) {
      RequestBuilder builder = new RequestBuilder(request);
      builder.setHeader("Range", "bytes=" + request.getRangeOffset() + "-");
      request = builder.build();
    }
    fc = new FilterContext.FilterContextBuilder<>(fc).request(request).build();
    return fc;
  }
DefaultAsyncHttpClient的preProcessRequest方法遍歷config.getRequestFilters(),挨個(gè)執(zhí)行asyncFilter.filter(fc)

executeRequest

org/asynchttpclient/DefaultAsyncHttpClient.java

public <T> ListenableFuture<T> executeRequest(Request request, AsyncHandler<T> handler) {
    if (config.getCookieStore() != null) {
      try {
        List<Cookie> cookies = config.getCookieStore().get(request.getUri());
        if (!cookies.isEmpty()) {
          RequestBuilder requestBuilder = new RequestBuilder(request);
          for (Cookie cookie : cookies) {
            requestBuilder.addOrReplaceCookie(cookie);
          }
          request = requestBuilder.build();
        }
      } catch (Exception e) {
        handler.onThrowable(e);
        return new ListenableFuture.CompletedFailure<>("Failed to set cookies of request", e);
      }
    }

    if (noRequestFilters) {
      return execute(request, handler);
    } else {
      FilterContext<T> fc = new FilterContext.FilterContextBuilder<T>().asyncHandler(handler).request(request).build();
      try {
        fc = preProcessRequest(fc);
      } catch (Exception e) {
        handler.onThrowable(e);
        return new ListenableFuture.CompletedFailure<>("preProcessRequest failed", e);
      }

      return execute(fc.getRequest(), fc.getAsyncHandler());
    }
  }
executeRequest方法對(duì)于noRequestFilters為false會(huì)執(zhí)行preProcessRequest

小結(jié)

AsyncHttpClient的RequestFilter定義了filter方法,它有一個(gè)實(shí)現(xiàn)類(lèi)為T(mén)hrottleRequestFilter,使用信號(hào)量用于對(duì)請(qǐng)求進(jìn)行限流;

DefaultAsyncHttpClient的executeRequest方法對(duì)于noRequestFilters為false會(huì)執(zhí)行preProcessRequest,而preProcessRequest方法遍歷config.getRequestFilters(),挨個(gè)執(zhí)行asyncFilter.filter(fc)。

以上就是AsyncHttpClient RequestFilter請(qǐng)求篩選源碼解讀的詳細(xì)內(nèi)容,更多關(guān)于AsyncHttpClient RequestFilter的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring實(shí)戰(zhàn)之獲取其他Bean的屬性值操作示例

    Spring實(shí)戰(zhàn)之獲取其他Bean的屬性值操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之獲取其他Bean的屬性值操作,結(jié)合實(shí)例形式分析了Spring操作Bean屬性值的相關(guān)配置與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-12-12
  • 老生常談java路徑中的反斜杠和斜杠的區(qū)別

    老生常談java路徑中的反斜杠和斜杠的區(qū)別

    下面小編就為大家?guī)?lái)一篇老生常談java路徑中的反斜杠和斜杠的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • SpringBoot實(shí)現(xiàn)文件上傳接口

    SpringBoot實(shí)現(xiàn)文件上傳接口

    這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)文件上傳接口,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Spring AOP定義AfterReturning增加實(shí)例分析

    Spring AOP定義AfterReturning增加實(shí)例分析

    這篇文章主要介紹了Spring AOP定義AfterReturning增加,結(jié)合實(shí)例形式分析了Spring面相切面AOP定義AfterReturning增加相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • java中的前++和后++的區(qū)別示例代碼詳解

    java中的前++和后++的區(qū)別示例代碼詳解

    這篇文章主要介紹了java中的前++和后++的區(qū)別示例代碼詳解,其實(shí)大家只要記住一句話就可以了,前++是先自加再使用而后++是先使用再自加,本文通過(guò)代碼給大家詳細(xì)解說(shuō),感興趣的朋友跟隨小編一起看看吧
    2020-06-06
  • Spring Boot 參數(shù)校驗(yàn)的具體實(shí)現(xiàn)方式

    Spring Boot 參數(shù)校驗(yàn)的具體實(shí)現(xiàn)方式

    這篇文章主要介紹了Spring Boot 參數(shù)校驗(yàn)的具體實(shí)現(xiàn)方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼

    Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼

    這篇文章主要為大家介紹了Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-03-03
  • Java中的序列化(Serializable)和反序列化

    Java中的序列化(Serializable)和反序列化

    這篇文章主要介紹了Java中的序列化(Serializable)和反序列化,?JAVA序列化與反序列化就是JAVA對(duì)象與一串字節(jié)流之間的相互轉(zhuǎn)換,?我們?cè)诔绦蛑袆?chuàng)建的JAVA對(duì)象只存在于JVM中,需要的朋友可以參考下
    2023-09-09
  • Java格式化輸出詳細(xì)講解(printf、print、println、format等)

    Java格式化輸出詳細(xì)講解(printf、print、println、format等)

    Java的格式化輸出等同于String.Format,與C有很大的相似,下面這篇文章主要給大家介紹了關(guān)于Java格式化輸出(printf、print、println、format等)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • 關(guān)于注解式的分布式Elasticsearch的封裝案例

    關(guān)于注解式的分布式Elasticsearch的封裝案例

    這篇文章主要介紹了關(guān)于注解式的分布式Elasticsearch的封裝案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01

最新評(píng)論