溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spring的autowire-candidate設(shè)計原理

發(fā)布時間:2021-06-22 13:39:21 來源:億速云 閱讀:172 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Spring的autowire-candidate設(shè)計原理”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

目錄
  • Xml配置文件中的default-autowire-candidates屬性

  • 匹配邏輯算法

    • PatternMatchUtils.simpleMatch

  • 總結(jié)

    Xml配置文件中的default-autowire-candidates屬性

    有的同學(xué)對這個配置可能不熟悉或者說都不知道這個配置的存在,那首先我們看下default-autowire-candidates這個配置是放在何處的:

    <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
             default-autowire-candidates="service*">
    
        <bean id="serviceA" class="org.wonder.frame.xmlConfig.SetterBean$ServiceA" autowire-candidate="false"/>
        <bean id="serviceB" class="org.wonder.frame.xmlConfig.SetterBean$ServiceB"  />
        <bean id="setterBean" class="org.wonder.frame.xmlConfig.SetterBean" autowire="byType" />
    </beans>

    在idea中我們可以點開 default-autowire-candidates這個屬性所在的spring-beans.xsd就能看到官方對這個屬性的注釋:

    A default bean name pattern for identifying autowire candidates: e.g. "Service", "data", "Service", "dataService". Also accepts a comma-separated list of patterns: e.g. "Service,*Dao". See the documentation for the 'autowire-candidate' attribute of the 'bean' element for the semantic details of autowire candidate beans.

    簡單翻譯下也就是說這個屬性可以標(biāo)示配置文件中的所有Bean默認(rèn)能否成為自動注入候選者的名稱匹配模式,比如 "Service", "data", "Service", "dataService".也支持以逗號分隔的字符串模式列表:"Service,Dao". 比如上面配置文件中配置的service\就匹配了serviceA,serviceB兩個Bean.但是Spring的設(shè)計規(guī)定serviceA自身配置的autowire-candidate為false會覆蓋default-autowire-candidates配置,所以serviceA是不會成為自動注入的候選者。

    匹配邏輯算法

    我們深入到源碼中看下Spring是如何根據(jù)這個匹配模式來與自身bean名稱來匹配的

    String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
    if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
       String candidatePattern = this.defaults.getAutowireCandidates();
       if (candidatePattern != null) {
          String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
          bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
       }
    }
    else {
       bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
    }

    很清楚,在bean本身配置autowire-candidate為空或者默認(rèn)的情況下,Spring會把default-autowire-candidates字符串轉(zhuǎn)換成數(shù)組,然后依賴PatternMatchUtils類的simpleMatch方法來驗證當(dāng)前bean的名稱是否匹配,成功與否都會賦值給當(dāng)前bean的autowireCandidate屬性。其實最主要的還是PatternMatchUtils.simpleMatch方法

    PatternMatchUtils.simpleMatch

    public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
       //pattern 匹配模式為空 或者待匹配字符串為空就返回false
       if (pattern == null || str == null) {
          return false;
       }
       //找到第一個* 在匹配模式字符串中的的索引
       int firstIndex = pattern.indexOf('*');
       if (firstIndex == -1) {
          //索引為空的情況下就代表 模式字符串要和待匹配字符串相等。
          return pattern.equals(str);
       }
       //*在第一位
       if (firstIndex == 0) {
          //*在第一位 且匹配模式字符串長度為1 那就直接返回true ,比如 *
          if (pattern.length() == 1) {
             return true;
          }
          //找到下一個*的起始位置
          int nextIndex = pattern.indexOf('*', firstIndex + 1);
          if (nextIndex == -1) {
             //如果沒有*了,就判斷 待匹配的字符串是否是以pattern結(jié)尾的。
             //比如*service   Aservice就滿足這種情況
             return str.endsWith(pattern.substring(1));
          }
          //截取第一個* 和之后一個* 之間的字符串
          String part = pattern.substring(1, nextIndex);
          if (part.isEmpty()) {
             return simpleMatch(pattern.substring(nextIndex), str);
          }
          //str 是指待匹配的字符
          int partIndex = str.indexOf(part);
          while (partIndex != -1) {
             if (simpleMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length()))) {
                return true;
             }
             //從partIndex+1 開始計算part的索引
             partIndex = str.indexOf(part, partIndex + 1);
          }
          return false;
       }
       //待匹配字符串的長度比 第一個*的索引 大或者相等的情況下
       //截取模式字符串 0 到 第一個*號之間的字符串 ,截取 待匹配字符串 0 到 第一個*號之間的字符串 對比
       //如果相等 ,再截取 模式字符串  第一個*號之后的字符串 和 待匹配 字符串  第一個*號之后的字符串 去做匹配
       return (str.length() >= firstIndex &&
             pattern.substring(0, firstIndex).equals(str.substring(0, firstIndex)) &&
             simpleMatch(pattern.substring(firstIndex), str.substring(firstIndex)));
    }

    這個Utils類的工具函數(shù)實現(xiàn)的字符串模糊匹配算法在我們?nèi)粘i_發(fā)中對字符串的操作方面也會有或多或少的幫助。

    總結(jié)

    Spring中的很多設(shè)計細(xì)節(jié)總是給我們很多驚喜,從中我們也可以很多小技巧,給我們?nèi)粘i_發(fā)會帶來不少啟發(fā)。

    “Spring的autowire-candidate設(shè)計原理”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI