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

Spring Bean 依賴注入常見錯(cuò)誤問題

 更新時(shí)間:2021年09月14日 10:29:46   作者:JavaEdge.  
這篇文章主要介紹了Spring Bean 依賴注入常見錯(cuò)誤問題,文中提到value的工作大體分為三個(gè)核心步驟,具體內(nèi)容詳情跟隨小編一起看看吧

有時(shí)我們會使用@Value自動(dòng)注入,同時(shí)也存在注入到集合、數(shù)組等復(fù)雜類型的場景。這都是方便寫 bug 的場景。

1 @Value未注入預(yù)期值

在字段或方法/構(gòu)造函數(shù)參數(shù)級別使用,指示帶注釋元素的默認(rèn)值表達(dá)式。
通常用于表達(dá)式驅(qū)動(dòng)或?qū)傩则?qū)動(dòng)的依賴注入。 還支持處理程序方法參數(shù)的動(dòng)態(tài)解析
例如,在 Spring MVC 中,一個(gè)常見的用例是使用#{systemProperties.myProp} systemProperties.myProp #{systemProperties.myProp}樣式的 SpEL(Spring 表達(dá)式語言)表達(dá)式注入值。
或可使用${my.app.myProp}樣式屬性占位符注入值。

@Value實(shí)際處理由BeanPostProcessor執(zhí)行,這意味著不能在BeanPostProcessor或BeanFactoryPostProcessor類型中使用 @Value。

V.S Autowired

在裝配對象成員屬性時(shí),常使用@Autowired來裝配。但也使用@Value進(jìn)行裝配:

  • 使用@Autowired一般都不會設(shè)置屬性值
  • @Value必須指定一個(gè)字符串值,因其定義做了要求:

一般都會因 @Value 常用于String類型的裝配,誤以為其不能用于非內(nèi)置對象的裝配。

可用如下方式注入一個(gè)屬性成員:

使用 @Value更多是用來裝配String,而且支持多種強(qiáng)大的裝配方式

application.properties配置了這樣一個(gè)屬性:

user=admin
password=pass

然后我們在一個(gè)Bean中,分別定義兩個(gè)屬性來引用它們:

password返回了配置值,但user卻不是配置文件的指定值,而是PC用戶名。

答疑

有一個(gè)正確的,說明 @Value使用姿勢沒問題,但user為啥不正確?
這就得精通Spring到底如何根據(jù) @Value查詢值。

@Value的核心工作流程 DefaultListableBeanFactory#doResolveDependency

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    // ...
    Class<?> type = descriptor.getDependencyType();
      // 尋找@Value
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            // 解析Value值
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                  getMergedBeanDefinition(beanName) : null);
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         
         // 轉(zhuǎn)化Value解析的結(jié)果到裝配的類型
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         try {
            return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
         }
         catch (UnsupportedOperationException ex) {}
      }
    // ...
  }

@Value 的工作大體分為以下三個(gè)核心步驟。

1 尋找@Value

判斷這個(gè)屬性字段是否標(biāo)記為@Value:

QualifierAnnotationAutowireCandidateResolver#findValue

  •  valueAnnotationType就是 @Value


2 解析@Value的字符串值

若一個(gè)字段標(biāo)記了 @Value,則可拿到對應(yīng)字符串值,然后根據(jù)字符串值解析,最終解析的結(jié)果可能是一個(gè)字符串or對象,取決于字符串怎么寫。

3 將解析結(jié)果轉(zhuǎn)化為待裝配的對象的類型

當(dāng)拿到上一步生成的結(jié)果后,我們會發(fā)現(xiàn)可能和我們要裝配的類型不匹配。
比如定義的是UUID,而結(jié)果是個(gè)字符串,此時(shí)就會根據(jù)目標(biāo)類型來尋找轉(zhuǎn)化器執(zhí)行轉(zhuǎn)化:

分析可得問題關(guān)鍵在第二步,執(zhí)行過程:

這里是在解析嵌入的值,替換掉占位符。使用PropertySourcesPlaceholderConfigurer根據(jù)PropertySources替換。

當(dāng)使用 ${user} 獲取替換值時(shí),最終執(zhí)行的查找并非只在application.property文件。
可以發(fā)現(xiàn)如下“源”都是替換的依據(jù):

而具體的查找執(zhí)行,通過

PropertySourcesPropertyResolver#getProperty

獲取執(zhí)行方式

在解析Value字符串有順序,源都存在CopyOnWriteArrayList,啟動(dòng)時(shí)就被按序固定下來了,一個(gè)一個(gè)“源”順序查找,在其中一源找到后,就直接返回。

查看systemEnvironment源,發(fā)現(xiàn)剛好有個(gè)user和自定義的重合,且值不是admin。

所以這真是冤家路窄了,剛好系統(tǒng)環(huán)境變量(systemEnvironment)含同名配置。若沒有意識到它們的存在,起了同名字符串作為 @Value,就容易引發(fā)這類問題。

修正

避免使用同一個(gè)名稱,具體修改如下:

user.name=admin
user.password=pass

其實(shí)還是不行。
在systemProperties這個(gè)PropertiesPropertySource源中剛好存在user.name,真是無巧不成書。所以命名時(shí),我們一定要注意不僅要避免和環(huán)境變量沖突,也要注意避免和系統(tǒng)變量等其他變量沖突,才能從根本解決該問題。

Spring給我們提供了很多好用的功能,但是這些功能交織到一起后,就有可能讓我們誤入一些坑,只有了解它的運(yùn)行方式,我們才能迅速定位問題、解決問題。

到此這篇關(guān)于Spring Bean 依賴注入常見錯(cuò)誤的文章就介紹到這了,更多相關(guān)Spring Bean 依賴注入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot項(xiàng)目 文件上傳臨時(shí)目標(biāo)被刪除異常的處理方案

    SpringBoot項(xiàng)目 文件上傳臨時(shí)目標(biāo)被刪除異常的處理方案

    這篇文章主要介紹了SpringBoot項(xiàng)目 文件上傳臨時(shí)目標(biāo)被刪除異常的處理方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot短信驗(yàn)證碼登錄功能的實(shí)現(xiàn)

    springboot短信驗(yàn)證碼登錄功能的實(shí)現(xiàn)

    這篇文章主要介紹了springboot短信驗(yàn)證碼登錄功能的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Java?數(shù)據(jù)交換?Json?和?異步請求?Ajax詳解

    Java?數(shù)據(jù)交換?Json?和?異步請求?Ajax詳解

    Json(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交換格式,采用鍵值對的形式來表示數(shù)據(jù),它廣泛應(yīng)用于Web開發(fā)中,特別適合于前后端數(shù)據(jù)傳輸和存儲,這篇文章主要介紹了Java數(shù)據(jù)交換Json和異步請求Ajax,需要的朋友可以參考下
    2023-09-09
  • mybatis中的test語句失效處理方式

    mybatis中的test語句失效處理方式

    這篇文章主要介紹了mybatis中的test語句失效處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java mutable對象和immutable對象的區(qū)別說明

    Java mutable對象和immutable對象的區(qū)別說明

    這篇文章主要介紹了Java mutable對象和immutable對象的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JDK的下載、安裝與部署圖文教程

    JDK的下載、安裝與部署圖文教程

    這篇文章主要為大家詳細(xì)介紹了JDK的下載、安裝與部署圖文教程,感興趣的小伙伴們可以參考一下
    2016-06-06
  • MybatisPlus處理大表查詢的實(shí)現(xiàn)步驟

    MybatisPlus處理大表查詢的實(shí)現(xiàn)步驟

    在實(shí)際工作中當(dāng)指定查詢數(shù)據(jù)過大時(shí),我們一般使用分頁查詢的方式一頁一頁的將數(shù)據(jù)放到內(nèi)存處理,本文主要介紹了MybatisPlus處理大表查詢的實(shí)現(xiàn)步驟,感興趣的可以了解一下
    2024-08-08
  • java 字符串轉(zhuǎn)化為字符數(shù)組的3種實(shí)現(xiàn)案例

    java 字符串轉(zhuǎn)化為字符數(shù)組的3種實(shí)現(xiàn)案例

    這篇文章主要介紹了java 字符串轉(zhuǎn)化為字符數(shù)組的3種實(shí)現(xiàn)案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 詳解spring boot集成RabbitMQ

    詳解spring boot集成RabbitMQ

    RabbitMQ作為AMQP的代表性產(chǎn)品,在項(xiàng)目中大量使用。結(jié)合現(xiàn)在主流的spring boot,極大簡化了開發(fā)過程中所涉及到的消息通信問題。
    2017-03-03
  • java基于odbc連接oracle的實(shí)現(xiàn)方法

    java基于odbc連接oracle的實(shí)現(xiàn)方法

    這篇文章主要介紹了java基于odbc連接oracle的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了連接操作的具體步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-09-09

最新評論