一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Bean 依賴注入常見錯誤問題

Spring Bean 依賴注入常見錯誤問題

2021-12-30 13:50JavaEdge. Java教程

這篇文章主要介紹了Spring Bean 依賴注入常見錯誤問題,文中提到value的工作大體分為三個核心步驟,具體內容詳情跟隨小編一起看看吧

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

1 @Value未注入預期值

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

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

V.S Autowired

在裝配對象成員屬性時,常使用@Autowired來裝配。但也使用@Value進行裝配:

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

Spring Bean 依賴注入常見錯誤問題

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

可用如下方式注入一個屬性成員:

Spring Bean 依賴注入常見錯誤問題

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

Spring Bean 依賴注入常見錯誤問題

application.properties配置了這樣一個屬性:

user=admin
password=pass

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

Spring Bean 依賴注入常見錯誤問題

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

答疑

有一個正確的,說明 @Value使用姿勢沒問題,但user為啥不正確?
這就得精通Spring到底如何根據 @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);
         }
         
         // 轉化Value解析的結果到裝配的類型
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         try {
            return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
         }
         catch (UnsupportedOperationException ex) {}
      }
    // ...
  }

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

1 尋找@Value

判斷這個屬性字段是否標記為@Value:

QualifierAnnotationAutowireCandidateResolver#findValue

  •  valueAnnotationType就是 @Value

Spring Bean 依賴注入常見錯誤問題
Spring Bean 依賴注入常見錯誤問題

2 解析@Value的字符串值

若一個字段標記了 @Value,則可拿到對應字符串值,然后根據字符串值解析,最終解析的結果可能是一個字符串or對象,取決于字符串怎么寫。

3 將解析結果轉化為待裝配的對象的類型

當拿到上一步生成的結果后,我們會發現可能和我們要裝配的類型不匹配。
比如定義的是UUID,而結果是個字符串,此時就會根據目標類型來尋找轉化器執行轉化:

Spring Bean 依賴注入常見錯誤問題

分析可得問題關鍵在第二步,執行過程:

Spring Bean 依賴注入常見錯誤問題

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

當使用 ${user} 獲取替換值時,最終執行的查找并非只在application.property文件。
可以發現如下“源”都是替換的依據:

Spring Bean 依賴注入常見錯誤問題

而具體的查找執行,通過

PropertySourcesPropertyResolver#getProperty

獲取執行方式

Spring Bean 依賴注入常見錯誤問題

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

查看systemEnvironment源,發現剛好有個user和自定義的重合,且值不是admin。

Spring Bean 依賴注入常見錯誤問題

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

修正

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

user.name=admin
user.password=pass

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

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

到此這篇關于Spring Bean 依賴注入常見錯誤的文章就介紹到這了,更多相關Spring Bean 依賴注入內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/qq_33589510/article/details/120246020

延伸 · 閱讀

精彩推薦
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
主站蜘蛛池模板: 国内外成人在线视频 | 色综合天天综合中文网 | 日本人护士免费xxxx视频 | 99re这里只有精品视频在线观看 | 亚洲一欧洲中文字幕在线 | 翁公与小莹在客厅激情 | 久久精品AV一区二区无码 | 精品第一国产综合精品蜜芽 | 午夜在线观看免费完整直播网 | 小辣椒精品福利视频导航 | 91久久偷偷做嫩草影院电 | 91国语精品自产拍在线观看一 | 日韩手机在线观看 | 好爽好紧小雪别夹小说 | 九九热在线观看视频 | 满溢游泳池免费 | 青青成人 | 纲手被漫画aⅴ | 女主被男主做哭失禁高h | 俄罗斯freeⅹ性欧美 | 日韩国产成人精品视频 | 精品一久久香蕉国产二月 | 99热这里只有精品久久免费 | 久久亚洲免费视频 | 国产高清在线精品一区 | 石原莉奈被店长侵犯免费 | 国产成人理在线观看视频 | 日韩高清在线高清免费 | 俺去啦最新地址 | 国产福利不卡视频在免费 | 亚洲AV国产国产久青草 | 人人干97 | 男女做受快插大片 | 免费看成年视频网页 | 久久精品人人做人人爽97 | 青草国产在线观看 | 九九精品国产兔费观看久久 | 特黄特色大片免费视频播放 | 亚洲国产货青视觉盛宴 | 亚洲精品黄色 | 国产欧美一区视频在线观看 |