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

Java 中責任鏈模式實現(xiàn)的三種方式

 更新時間:2017年09月11日 11:16:25   作者:atheva  
本文重點給大家介紹java中如何編寫責任鏈模式。主要從下面3個框架中的代碼中介紹。非常不錯,需要的朋友參考下吧

責任鏈模式

責任鏈模式的定義:使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接受者之間的耦合關(guān)系, 將這個對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理他為止。這里就不再過多的介紹什么是責任鏈模式,主要來說說java中如何編寫。主要從下面3個框架中的代碼中介紹。

  • servlet中的filter
  • dubbo中的filter
  • mybatis中的plugin 這3個框架在實現(xiàn)責任鏈方式不盡相同。

servlet中的Filter

servlet中分別定義了一個 Filter和FilterChain的接口,核心代碼如下:

public final class ApplicationFilterChain implements FilterChain {
  private int pos = 0; //當前執(zhí)行filter的offset
  private int n; //當前filter的數(shù)量
  private ApplicationFilterConfig[] filters; //filter配置類,通過getFilter()方法獲取Filter
  private Servlet servlet
  @Override
  public void doFilter(ServletRequest request, ServletResponse response) {
    if (pos < n) {
      ApplicationFilterConfig filterConfig = filters[pos++];
      Filter filter = filterConfig.getFilter();
      filter.doFilter(request, response, this);
    } else {
      // filter都處理完畢后,執(zhí)行servlet
      servlet.service(request, response);
    }
  }
}

代碼還算簡單,結(jié)構(gòu)也比較清晰,定義一個Chain,里面包含了Filter列表和servlet,達到在調(diào)用真正servlet之前進行各種filter邏輯。

Dubbo中的Filter

Dubbo在創(chuàng)建Filter的時候是另外一個方法,通過把Filter封裝成 Invoker的匿名類,通過鏈表這樣的數(shù)據(jù)結(jié)構(gòu)來完成責任鏈,核心代碼如下:

private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
  Invoker<T> last = invoker;
  //只獲取滿足條件的Filter
  List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
  if (filters.size() > 0) {
    for (int i = filters.size() - 1; i >= 0; i --) {
      final Filter filter = filters.get(i);
      final Invoker<T> next = last;
      last = new Invoker<T>() {
        ...
        public Result invoke(Invocation invocation) throws RpcException {
          return filter.invoke(next, invocation);
        }
        ...
      };
    }
  }
  return last;
}

Dubbo的責任鏈就沒有類似FilterChain這樣的類吧Filter和調(diào)用Invoker結(jié)合起來,而是通過創(chuàng)建一個鏈表,調(diào)用的時候我們只知道第一個節(jié)點,每個節(jié)點包含了下一個調(diào)用的節(jié)點信息。 這里的雖然Invoker封裝Filter沒有顯示的指定next,但是通過java匿名類和final的機制達到同樣的效果。

Mybatis中的Plugin

Mybatis可以配置各種Plugin,無論是官方提供的還是自己定義的,Plugin和Filter類似,就在執(zhí)行Sql語句的時候做一些操作。Mybatis的責任鏈則是通過動態(tài)代理的方式,使用Plugin代理實際的Executor類。(這里實際還使用了組合模式,因為Plugin可以嵌套代理),核心代碼如下:

public class Plugin implements InvocationHandler{
  private Object target;
  private Interceptor interceptor;
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
    if (滿足代理條件) {
      return interceptor.intercept(new Invocation(target, method, args));
    }
    return method.invoke(target, args);   
  }
  //對傳入的對象進行代理,可能是實際的Executor類,也可能是Plugin代理類
  public static Object wrap(Object target, Interceptor interceptor) {
    Class<?> type = target.getClass();
    Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
    if (interfaces.length > 0) {
      return Proxy.newProxyInstance(
          type.getClassLoader(),
          interfaces,
          new Plugin(target, interceptor, signatureMap));
    }
    return target;
  }
}

 簡單的示意圖如下:

總結(jié)

這里簡單介紹了Servlet、Dubbo、Mybatis對責任鏈模式的不同實現(xiàn)手段,其中Servlet是相對比較清晰,又易于實現(xiàn)的方式,而Dubbo和Mybatis則適合在原有代碼基礎(chǔ)上,增加責任鏈模式代碼改動量最小的。

以上所述是小編給大家介紹的Java 中責任鏈模式實現(xiàn)的三種方式,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Java線性結(jié)構(gòu)中棧、隊列和串的基本概念和特點詳解

    Java線性結(jié)構(gòu)中棧、隊列和串的基本概念和特點詳解

    前幾天小編給大家介紹了Java線性結(jié)構(gòu)中的鏈表,除了鏈表這種結(jié)構(gòu)之外,實際上還有棧、隊列、串等結(jié)構(gòu),那么這些結(jié)構(gòu)又有哪些特點呢,本文就給大家詳細的介紹一下,感興趣的小伙伴跟著小編一起來看看吧
    2023-07-07
  • javaweb 項目初始配置的方法步驟

    javaweb 項目初始配置的方法步驟

    本文主要介紹了javaweb 項目初始配置的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 一個applicationContext 加載錯誤導(dǎo)致的阻塞問題及解決方法

    一個applicationContext 加載錯誤導(dǎo)致的阻塞問題及解決方法

    這篇文章主要介紹了一個applicationContext 加載錯誤導(dǎo)致的阻塞問題及解決方法,需要的朋友可以參考下
    2018-11-11
  • Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例

    Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例

    這篇文章主要介紹了Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • spring?boot?3使用?elasticsearch?提供搜索建議的實例詳解

    spring?boot?3使用?elasticsearch?提供搜索建議的實例詳解

    這篇文章主要介紹了spring?boot3使用elasticsearch提供搜索建議,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能

    SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能

    這篇文章主要介紹了SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • Springboot重寫addInterceptors()方法配置攔截器實例

    Springboot重寫addInterceptors()方法配置攔截器實例

    這篇文章主要介紹了Springboot重寫addInterceptors()方法配置攔截器實例,spring?boot拋棄了復(fù)雜的xml配置,我們可以自定義配置類(標注@Configuration注解的類)來實現(xiàn)WebMvcConfigurer接口,并重寫addInterceptors()方法來配置攔截器,需要的朋友可以參考下
    2023-09-09
  • 詳解Java?redis中緩存穿透?緩存擊穿?雪崩三種現(xiàn)象以及解決方法

    詳解Java?redis中緩存穿透?緩存擊穿?雪崩三種現(xiàn)象以及解決方法

    緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),而用戶不斷發(fā)起請求,如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)。這時的用戶很可能是攻擊者,攻擊會導(dǎo)致數(shù)據(jù)庫壓力過大
    2022-01-01
  • @RereshScope刷新的原理詳解

    @RereshScope刷新的原理詳解

    在配合配置中心修改配置讓應(yīng)用自動刷新配置時,我們要在需要感知配置變化的bean上面加上@RereshScope。如果我們不加上這注解,那么有可能無法完成配置自動刷新。本文就來和大家講講@RereshScope刷新的原理,需要的可以參考一下
    2022-12-12
  • Spring Boot下如何自定義Repository中的DAO方法

    Spring Boot下如何自定義Repository中的DAO方法

    這篇文章主要介紹了Spring Boot下如何自定義Repository中的DAO方法,需要的朋友可以參考下
    2017-06-06

最新評論