日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

springboot中@Value的工作原理說明

瀏覽:66日期:2023-02-27 14:27:27

我們知道springboot中的Bean組件的成員變量(屬性)如果加上了@Value注解,可以從有效的配置屬性資源中找到配置項進行綁定,那么這一切是怎么發生的呢?

下文將簡要分析一下@Value的工作原理。

springboot版本: springboot-2.0.6.RELEASE

概述

springboot啟動過程中,有兩個比較重要的過程,如下:

1 掃描,解析容器中的bean注冊到beanFactory上去,就像是信息登記一樣。

2 實例化、初始化這些掃描到的bean。

@Value的解析就是在第二個階段。BeanPostProcessor定義了bean初始化前后用戶可以對bean進行操作的接口方法,它的一個重要實現類AutowiredAnnotationBeanPostProcessor正如javadoc所說的那樣,為bean中的@Autowired和@Value注解的注入功能提供支持。

解析流程調用鏈時序圖

@Value解析過程中的主要調用鏈,我用以下時序圖來表示:

springboot中@Value的工作原理說明

這里先簡單介紹一下圖上的幾個類的作用。

AbstractAutowireCapableBeanFactory: 提供了bean創建,屬性填充,自動裝配,初始胡。支持自動裝配構造函數,屬性按名稱和類型裝配。實現了AutowireCapableBeanFactory接口定義的createBean方法。

AutowiredAnnotationBeanPostProcessor: 裝配bean中使用注解標注的成員變量,setter方法, 任意的配置方法。比較典型的是@Autowired注解和@Value注解。

InjectionMetadata: 類的注入元數據,可能是類的方法或屬性等,在AutowiredAnnotationBeanPostProcessor類中被使用。

AutowiredFieldElement: 是AutowiredAnnotationBeanPostProcessor的一個私有內部類,繼承InjectionMetadata.InjectedElement,描述注解的字段。

StringValueResolver: 一個定義了處置字符串值的接口,只有一個接口方法resolveStringValue,可以用來解決占位符字符串。本文中的主要實現類在PropertySourcesPlaceholderConfigurer#processProperties方法中通過lamda表達式定義的。供ConfigurableBeanFactory類使用。

PropertySourcesPropertyResolver: 屬性資源處理器,主要功能是獲取PropertySources屬性資源中的配置鍵值對。

PropertyPlaceholderHelper: 一個工具類,用來處理帶有占位符的字符串。形如${name}的字符串在該工具類的幫助下,可以被用戶提供的值所替代。替代途經可能通過Properties實例或者PlaceholderResolver(內部定義的接口)。

PropertyPlaceholderConfigurerResolver: 上一行所說的PlaceholderResolver接口的一個實現類,是PropertyPlaceholderConfigurer類的一個私有內部類。實現方法resolvePlaceholder中調用了外部類的resolvePlaceholder方法。

調用鏈說明

這里主要介紹一下調用鏈中的比較重要的方法。

AbstractAutowireCapableBeanFactory#populateBean方法用于填充bean屬性,執行完后可獲取屬性裝配后的bean。

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { ...if (hasInstAwareBpps) {// 遍歷所有InstantiationAwareBeanPostProcessor實例設置屬性字段值。for (BeanPostProcessor bp : getBeanPostProcessors()) {// AutowiredAnnotationBeanPostProcessor會進入此分支if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);//上行代碼執行后,bw.getWrappedInstance()就得到了@Value注解裝配屬性后的bean了if (pvs == null) {return;}}}}...}

InjectionMetadata#inject逐個裝配bean的配置屬性。

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Collection<InjectedElement> checkedElements = this.checkedElements;Collection<InjectedElement> elementsToIterate =(checkedElements != null ? checkedElements : this.injectedElements);if (!elementsToIterate.isEmpty()) { // 依次注入屬性for (InjectedElement element : elementsToIterate) {if (logger.isDebugEnabled()) {logger.debug('Processing injected element of bean ’' + beanName + '’: ' + element);}element.inject(target, beanName, pvs);}}}

PropertyPlaceholderHelper#parseStringValue解析屬性值

/** * 一個參數示例 value = '${company.ceo}' * */protected String parseStringValue(String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {StringBuilder result = new StringBuilder(value);// this.placeholderPrefix = '${'int startIndex = value.indexOf(this.placeholderPrefix);while (startIndex != -1) {// 占位符的結束位置,以value = '${company.ceo}'為例,endIndex=13int endIndex = findPlaceholderEndIndex(result, startIndex);if (endIndex != -1) {// 獲取{}里的真正屬性名稱,此例為'company.ceo'String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);String originalPlaceholder = placeholder;if (!visitedPlaceholders.add(originalPlaceholder)) {throw new IllegalArgumentException('Circular placeholder reference ’' + originalPlaceholder + '’ in property definitions');}// Recursive invocation, parsing placeholders contained in the placeholder key.// 遞歸調用本方法,因為屬性鍵中可能仍然有占位符placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);// Now obtain the value for the fully resolved key...// 獲取屬性鍵placeholder對應的屬性值String propVal = placeholderResolver.resolvePlaceholder(placeholder);// 此處邏輯是當company.ceo=${bi:li}時,company.ceo最終被li所替代的原因// 所以配置文件中,最好不要出現類似${}的東西,因為它本身就會被spring框架所解析if (propVal == null && this.valueSeparator != null) {int separatorIndex = placeholder.indexOf(this.valueSeparator);if (separatorIndex != -1) {String actualPlaceholder = placeholder.substring(0, separatorIndex);String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);if (propVal == null) {propVal = defaultValue;}}}if (propVal != null) {// Recursive invocation, parsing placeholders contained in the// previously resolved placeholder value.propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);// 將${company.ceo}替換為liresult.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);if (logger.isTraceEnabled()) {logger.trace('Resolved placeholder ’' + placeholder + '’');}startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());}else if (this.ignoreUnresolvablePlaceholders) {// Proceed with unprocessed value.startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());}else {throw new IllegalArgumentException('Could not resolve placeholder ’' +placeholder + '’' + ' in value '' + value + ''');}visitedPlaceholders.remove(originalPlaceholder);}else {startIndex = -1;}}return result.toString();}總結

@Value注解標注的bean屬性裝配是依靠AutowiredAnnotationBeanPostProcessor在bean的實例化、初始化階段完成的。以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国内精品福利| 在线免费观看亚洲| 中文字幕一区二区三区日韩精品 | 日韩精品一区第一页| 亚洲午夜久久| 1024精品一区二区三区| 欧美日韩国产观看视频| 成人欧美一区二区三区的电影| 欧美国产另类| 国产在线观看91一区二区三区| 久久精品九色| 欧美男人天堂| 99riav国产精品| 综合国产精品| 久久国产三级| 国产精品国产一区| 九九久久电影| 欧美日韩亚洲三区| 91日韩免费| 久久成人亚洲| 97成人超碰| 欧美日韩国产v| 久久国产欧美日韩精品| 精品亚洲二区| 9色国产精品| 久久久免费人体| 欧美特黄一区| 精品午夜久久| 免费人成黄页网站在线一区二区| 日韩国产91| 婷婷综合亚洲| 亚洲一区亚洲| 久久这里只有| 日韩有码av| 国产伊人精品| 日韩精品一级| 麻豆一区二区三| 日韩av三区| 三级精品视频| 麻豆国产精品| 国产一区导航| 欧美1区2区3区| 国产精品久久久久久久久免费高清 | 夜夜嗨av一区二区三区网站四季av| 日韩激情一二三区| 激情婷婷亚洲| 色偷偷色偷偷色偷偷在线视频| 日本精品国产| 欧美日韩一二| 日韩二区三区四区| 伊人久久成人| 欧美日韩尤物久久| 日韩一区二区中文| 精品无人区麻豆乱码久久久| 欧美影院精品| 69堂精品视频在线播放| 亚洲精选成人| 91av亚洲| 日本美女一区| 丝袜av一区| 久久久久久黄| 欧美天堂亚洲电影院在线观看| 久久久久国产精品一区三寸| 久久影院午夜精品| 在线看片福利| 日韩啪啪电影网| 岛国av在线网站| 免费不卡在线观看| 欧美色图国产精品| 欧美不卡高清一区二区三区| 欧美韩日一区| 久久精品123| 婷婷激情一区| 国产精品日韩| 日本成人一区二区| 国产欧美在线| 91一区二区三区四区| 久久国产成人午夜av影院宅| 亚洲视频播放| 91亚洲精品在看在线观看高清| 免费在线亚洲欧美| 久久久噜噜噜| 亚洲aa在线| www.九色在线| 免费视频最近日韩| 鲁大师精品99久久久| 老司机久久99久久精品播放免费| 99精品视频在线| 综合日韩在线| 国产一区二区三区四区五区传媒 | 欧美日韩免费看片| 伊人久久一区| 国产精品成久久久久| 999国产精品999久久久久久| 日本在线观看不卡视频| 国产成人精品一区二区三区在线| 亚洲午夜一级| 九九99久久精品在免费线bt| 91超碰国产精品| 91精品啪在线观看国产爱臀| 高清精品久久| 日韩欧美久久| 日韩一区二区久久| 欧美一级全黄| 99视频精品| 9999国产精品| 国产乱码精品一区二区亚洲| 午夜国产一区二区| 91欧美国产| 毛片不卡一区二区| 91欧美精品| 丝袜脚交一区二区| 欧美综合另类| 四季av一区二区凹凸精品| 美女尤物久久精品| 亚洲午夜电影| 黑人精品一区| 成人在线免费观看91| 久久精品97| 日本电影久久久| 亚洲精品免费观看| 在线看片日韩| 四虎在线精品| 日韩精品乱码av一区二区| 久久av一区| 亚洲毛片一区| 日韩二区在线观看| 日韩av字幕| 欧美精品中文| 欧美一区91| 欧美日韩午夜电影网| 日韩午夜视频在线| 国产亚洲观看| 欧美黄页在线免费观看 | 99久久夜色精品国产亚洲1000部| 深夜视频一区二区| 亚洲激情久久| 视频一区二区三区在线| 日韩三级一区| 国产不卡精品在线| 欧美另类专区| 日韩高清在线不卡| 国产精品一区二区av日韩在线| 精品国产91| 激情视频一区二区三区| 亚洲一区二区三区在线免费| 日本不卡视频在线观看| 精品三级在线| 国产视频亚洲| 欧美精品91| 亚洲精品国产偷自在线观看| 国产一区二区精品| 欧美a在线观看| 国产精品日韩久久久| 国产高清精品二区| 99热精品在线| 91一区二区三区四区| 国产精品外国| 亚洲黄色中文字幕| 色综合视频一区二区三区日韩| 久久久久亚洲精品中文字幕| 国产精品色网| 国产伦理久久久久久妇女| 性欧美xxxx免费岛国不卡电影| 性一交一乱一区二区洋洋av| 91嫩草精品| 亚洲天堂av影院| 亚洲综合中文| 欧美a级一区| 国产中文字幕一区二区三区| 91中文字幕精品永久在线| 日韩视频二区| 国产精品蜜月aⅴ在线| 亚洲激情偷拍| 日韩一区欧美| 麻豆精品在线播放| 日本在线成人| 亚洲精品三级| 日韩一区二区免费看| 亚洲欧美日韩国产一区二区| 日韩精选在线| 免费国产亚洲视频| 亚洲高清成人| 极品日韩av| 国内精品99| 亚洲精品小说| 一区二区自拍| 亚洲精品在线影院| 久久精品123| 欧美成a人免费观看久久| 日韩在线综合| 99精品视频精品精品视频| 91精品亚洲| 在线亚洲欧美| 亚洲精品大全| 国产麻豆一区二区三区精品视频| 国产调教精品| 精品欧美日韩精品| 日韩欧美二区| 狠狠久久婷婷|