最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Security內(nèi)置過(guò)濾器的維護(hù)方法

 更新時(shí)間:2022年02月22日 15:30:49   作者:碼農(nóng)小胖哥  
這篇文章主要介紹了Spring?Security的內(nèi)置過(guò)濾器是如何維護(hù)的,本文給我們分析一下HttpSecurity維護(hù)過(guò)濾器的幾個(gè)方法,需要的朋友可以參考下

Spring Security中的內(nèi)置過(guò)濾器順序是怎么維護(hù)的?我想很多開(kāi)發(fā)者都對(duì)這個(gè)問(wèn)題感興趣。本篇我和大家一起探討下這個(gè)問(wèn)題。

HttpSecurity包含了一個(gè)成員變量FilterOrderRegistration,這個(gè)類(lèi)是一個(gè)內(nèi)置過(guò)濾器注冊(cè)表。至于這些過(guò)濾器的作用,不是本文介紹的重點(diǎn),有興趣可以去看看FilterOrderRegistration的源碼。

內(nèi)置過(guò)濾器的順序

FilterOrderRegistration維護(hù)了一個(gè)變量filterToOrder,它記錄了類(lèi)之間的順序和上下之間的間隔步長(zhǎng)。我們復(fù)制了一個(gè)FilterOrderRegistration來(lái)直觀感受一下過(guò)濾器的順序:

CopyFilterOrderRegistration filterOrderRegistration = new CopyFilterOrderRegistration();
        // 獲取內(nèi)置過(guò)濾器  此方法并未提供
        Map<String, Integer> filterToOrder = filterOrderRegistration.getFilterToOrder();
        TreeMap<Integer, String> orderToFilter = new TreeMap<>();
        filterToOrder.forEach((name, order) -> orderToFilter.put(order,name));
        orderToFilter.forEach((order,name) -> System.out.println(" 順序:" + order+" 類(lèi)名:" + name ));

打印結(jié)果:

我們可以看得出內(nèi)置過(guò)濾器之間的位置是相對(duì)固定的,除了第一個(gè)跟第二個(gè)步長(zhǎng)為200外,其它步長(zhǎng)為100。

內(nèi)置過(guò)濾器并非一定會(huì)生效,僅僅是預(yù)置了它們的排位,需要通過(guò)HttpSecurity的addFilterXXXX系列方法顯式添加才行。

注冊(cè)過(guò)濾器的邏輯

FilterOrderRegistration提供了一個(gè)put方法:

 void put(Class<? extends Filter> filter, int position) {
  String className = filter.getName();
        // 如果這個(gè)類(lèi)已經(jīng)注冊(cè)就忽略
  if (this.filterToOrder.containsKey(className)) {
   return;
  }
        // 如果沒(méi)有注冊(cè)就注冊(cè)順序。
  this.filterToOrder.put(className, position);
 }

從這個(gè)方法我們可以得到幾個(gè)結(jié)論:

  • 內(nèi)置的34個(gè)過(guò)濾器是有固定序號(hào)的,不可被改變。
  • 新加入的過(guò)濾器的類(lèi)全限定名是不能和內(nèi)置過(guò)濾器重復(fù)的。
  • 新加入的過(guò)濾器的順序是可以和內(nèi)置過(guò)濾器的順序重復(fù)的。

獲取已注冊(cè)過(guò)濾器的順序值

FilterOrderRegistration還提供了一個(gè)getOrder方法:

  Integer getOrder(Class<?> clazz) {
        // 如果類(lèi)Class 或者 父類(lèi)Class 名為空就返回null
        while (clazz != null) {
            Integer result = this.filterToOrder.get(clazz.getName());
            // 如果獲取到順序值就返回
            if (result != null) {
                return result;
            }
            // 否則嘗試去獲取父類(lèi)的順序值
            clazz = clazz.getSuperclass();
        }
        return null;
    }

HttpSecurity維護(hù)過(guò)濾器的方法

接下來(lái)我們分析一下HttpSecurity維護(hù)過(guò)濾器的幾個(gè)方法。

addFilterAtOffsetOf

addFilterAtOffsetOf是一個(gè)HttpSecurity的內(nèi)置私有方法。Filter是想要注冊(cè)到DefaultSecurityFilterChain中的過(guò)濾器,offset是向右的偏移值,registeredFilter是已經(jīng)注冊(cè)到FilterOrderRegistration的過(guò)濾器,而且registeredFilter沒(méi)有注冊(cè)的話會(huì)空指針。

 private HttpSecurity addFilterAtOffsetOf(Filter filter, int offset, Class<? extends Filter> registeredFilter) {
        // 首先會(huì)根據(jù)registeredFilter的順序和偏移值來(lái)計(jì)算filter的
  int order = this.filterOrders.getOrder(registeredFilter) + offset;
        // filter添加到集合中待排序
  this.filters.add(new OrderedFilter(filter, order));
        // filter注冊(cè)到 FilterOrderRegistration
  this.filterOrders.put(filter.getClass(), order);
  return this;
 }

務(wù)必記著registeredFilter一定是已注冊(cè)入FilterOrderRegistration的Filter。

addFilter系列方法

這里以addFilterAfter為例。

 @Override
 public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) {
  return addFilterAtOffsetOf(filter, 1, afterFilter);
 }

addFilterAfter是將filter的位置置于afterFilter后一位,假如afterFilter順序值為400,則filter順序值為401。addFilterBefore和addFilterAt邏輯和addFilterAfter僅僅是偏移值的區(qū)別,這里不再贅述。

addFilter的方法比較特殊:

 @Override
 public HttpSecurity addFilter(Filter filter) {
  Integer order = this.filterOrders.getOrder(filter.getClass());
  if (order == null) {
   throw new IllegalArgumentException("The Filter class " + filter.getClass().getName()
     + " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.");
  }
  this.filters.add(new OrderedFilter(filter, order));
  return this;
 }

filter必須是已經(jīng)注冊(cè)到FilterOrderRegistration的Filter,這意味著它可能是內(nèi)置的Filter,也可能是先前通過(guò)addFilterBefore、addFilterAt或者addFilterAfter注冊(cè)的非內(nèi)置Filter。

問(wèn)題來(lái)了

之前看到一個(gè)問(wèn)題,如果HttpSecurity注冊(cè)兩個(gè)重復(fù)序號(hào)的Filter會(huì)是怎么樣的順序呢?我們先來(lái)看下排序的機(jī)制:

// filters
private List<OrderedFilter> filters = new ArrayList<>(); 
//排序
this.filters.sort(OrderComparator.INSTANCE);

看了下OrderComparator源碼,其實(shí)還是通過(guò)數(shù)字的自然排序,數(shù)字越小越靠前。如果數(shù)字相同,索引越小越靠前。也就是同樣的序號(hào),誰(shuí)先add到filters誰(shuí)就越靠前。

到此這篇關(guān)于Spring Security的內(nèi)置過(guò)濾器是如何維護(hù)的的文章就介紹到這了,更多相關(guān)Spring Security內(nèi)置過(guò)濾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA Integer類(lèi)常用方法解析

    JAVA Integer類(lèi)常用方法解析

    這篇文章主要介紹了JAVA Integer類(lèi)常用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • SpringBoot + SpringSecurity 短信驗(yàn)證碼登錄功能實(shí)現(xiàn)

    SpringBoot + SpringSecurity 短信驗(yàn)證碼登錄功能實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot + SpringSecurity 短信驗(yàn)證碼登錄功能實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Java ScheduledExecutorService的具體使用

    Java ScheduledExecutorService的具體使用

    ScheduledExecutorService有線程池的特性,也可以實(shí)現(xiàn)任務(wù)循環(huán)執(zhí)行,本文主要介紹了Java ScheduledExecutorService的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-05-05
  • Java 關(guān)系運(yùn)算符詳情及案例(下)

    Java 關(guān)系運(yùn)算符詳情及案例(下)

    這篇文章主要介紹了Java 關(guān)系運(yùn)算符詳情及案例的實(shí)現(xiàn),主要續(xù)上篇文章,上一篇文章我們講到“等于”運(yùn)算符 (==)、“不等于”運(yùn)算符(!=)、“大于”運(yùn)算符(>) ,這篇文章繼續(xù)給大家講解相關(guān)知識(shí),需要的朋友可以參考一下
    2021-12-12
  • 詳解static 和 final 和 static final區(qū)別

    詳解static 和 final 和 static final區(qū)別

    這篇文章主要介紹了static 和 final 和 static final區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Java調(diào)用Pytorch模型實(shí)現(xiàn)圖像識(shí)別

    Java調(diào)用Pytorch模型實(shí)現(xiàn)圖像識(shí)別

    這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用Pytorch實(shí)現(xiàn)圖像識(shí)別功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06
  • Spring事務(wù)注解@Transactional失效的八種場(chǎng)景分析

    Spring事務(wù)注解@Transactional失效的八種場(chǎng)景分析

    最近在開(kāi)發(fā)采用Spring框架的項(xiàng)目中,使用了@Transactional注解,但發(fā)現(xiàn)事務(wù)注解失效了,所以這篇文章主要給大家介紹了關(guān)于Spring事務(wù)注解@Transactional失效的八種場(chǎng)景,需要的朋友可以參考下
    2021-05-05
  • 詳解直接插入排序算法與相關(guān)的Java版代碼實(shí)現(xiàn)

    詳解直接插入排序算法與相關(guān)的Java版代碼實(shí)現(xiàn)

    這篇文章主要介紹了直接插入排序算法與相關(guān)的Java版代碼實(shí)現(xiàn),需要的朋友可以參考下
    2016-05-05
  • 淺談springBoot注解大全

    淺談springBoot注解大全

    本篇文章主要介紹了淺談springBoot注解大全,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Mybatis 一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn)

    Mybatis 一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn)

    mybatis作為一個(gè)流行的持久化工具,緩存必然是缺少不了的組件。通過(guò)這篇文章,就讓我們來(lái)了解一下一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05

最新評(píng)論

通州区| 合阳县| 三河市| 大冶市| 马山县| 尖扎县| 新巴尔虎右旗| 临泉县| 扶沟县| 宁德市| 南川市| 贵定县| 麟游县| 岳池县| 邵东县| 淮北市| 高邑县| 称多县| 金乡县| 萍乡市| 司法| 霍城县| 丰顺县| 南通市| 永宁县| 玉环县| 栾城县| 惠州市| 汾阳市| 德保县| 酉阳| 西充县| 清流县| 建平县| 仁怀市| 广昌县| 苗栗市| 抚顺市| 台前县| 申扎县| 普洱|