国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

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

服務器之家 - 編程語言 - Java教程 - springboot @Value實現獲取計算機中絕對路徑文件的內容

springboot @Value實現獲取計算機中絕對路徑文件的內容

2021-12-24 13:05mysgk Java教程

這篇文章主要介紹了springboot @Value實現獲取計算機中絕對路徑文件的內容,具有很好的參考價值,希望對大家有所幫助。

springboot @Value獲取絕對路徑文件的內容

默認情況下使用

@Value("aaa.txt")
private Resource txtResource;

這樣獲取到的是項目classpath 下的 aaa.txt

如果想獲取非項目路徑下的文件內容怎么辦呢,看了下@Value的好像也沒有說,

其實

@Value("https://www.baidu.com")
private Resource urlResource;

這樣是可以獲取到 百度首頁的內容的.它這里使用的是https協議.

同樣的我們可以使用file協議獲取文本的內容

即:

@Value("file:///E://aaa.txt")
private Resource txtResource;

使用@Value 有一個好處就是,你不用關心文本內容的變化,你每次調用的時候,springboot 會自動幫你重新加載.

 

Spring注解@Value解讀

主要通過源碼解讀來分析@Value實現屬性注入Spring Bean的過程,并對static類型字段無法通過@Value注入為Spring Bean依賴的原因做一個探究。

依賴注入概述

基于Spring MVC或者Spring Boot開發后端項目的時候總是繞不開Spring IOC容器,Spring IOC容器管理Spring Bean,我們可以通過XML或者注解的方式來定義一個Bean,如通過注解@Service,@Controller,@Component,@Repository或者@Bean加Java配置方式。實際應用中我們定義的一個Bean很多時候存在互相之間的依賴,比如Service層通過@Service定義的Bean往往要依賴數據庫DAO層通過@Repository定義的Bean,這時候我們往往通過@Autowired或@Resource來自動裝配,另外還有一些Bean內部的屬性(Field)需要通過配置文件中定義的值來設置,而后創建的Bean才是符合我們預期的,我們一般通過@Value和@ConfigurationProperties來實現屬性的注入。

實際應用案例

以文檔管理服務為例,我們有個資源上傳的接口,其依賴一個FeignClient客戶端Bean,一個業務邏輯處理的Service Bean,還依賴一個資源上傳的OSS的桶bucket成員變量,bucket和OSS我們通常配置在配置文件中以區分不同環境。具體的依賴關系如下圖:

springboot @Value實現獲取計算機中絕對路徑文件的內容

源碼解讀分析

首先看一下Spring Bean的的整個生命周期:

springboot @Value實現獲取計算機中絕對路徑文件的內容

在實例化對象完成后,設置屬性值(polulateBean)之前,會搜集類上的注解元數據信息,然后在polulalteBean中攔截,執行BeanPostProcessor中的方法,反射注入依賴的值。@Resource是jdk提供的注解,其使用的后置處理器是CommonAnnotationBeanPostProcessor,而@Autowired和@Value注解使用的后置處理器是AutowiredAnnotationBeanPostProcessor,具體的我們下面會通過代碼來解讀。

先來看一下BeanFactory和ApplicationContext在裝載bean時候的區別:

  • BeanFactory在啟動時不會去實例化Bean,當從容器中拿Bean的時候才會去實例化;
  • ApplicationContext在啟動時就把所有的Bean全部實例化了??梢詾锽ean配置lazy-init=true來讓Bean延遲實例化。

我們下面以Spring Boot和ApplicationContext來走讀一下源碼:

1、首先進入SpringApplication.run(XXXApplication.class, args)

然后一直進入到SpringApplication的refreshContext()方法,refreshContext()是IOC容器初始化的核心方法,完成容器上下文的刷新,主要包括各種處理器、監聽器以及Bean的初始化等工作。

springboot @Value實現獲取計算機中絕對路徑文件的內容

2、然后進入到AbstractApplicationContext的refresh()方法

中的finishBeanFactoryInitialization(beanFactory)方法,這個方法就是ApplicationContext完成Spring Bean實例化和初始化的關鍵方法。

springboot @Value實現獲取計算機中絕對路徑文件的內容

3、而后進入到DefaultListableBeanFactory的preInstantiateSingletons()方法

此方法就是獲取到所有的beanName,然后循環的去實例化+初始化bean,而實例化+初始化的方式就是調用其getBean(String name)方法,因此我們直接調到getBean(name) ,此方法的最終實現是在AbstractBeanFactory中,我們進入AbstractBeanFactory的getBean(beanName)查看,然后根據調用棧直接進入到AbstractBeanFactory的doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly)方法中。這個方法代碼較多,我們直接查看我們要關注的核心代碼段如下:

springboot @Value實現獲取計算機中絕對路徑文件的內容

4、然后我們進入到AbstractAutowireCapableBeanFactory

createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法中,其中AbstractAutowireCapableBeanFactory是AbstractBeanFactory的一個子類,AbstractBeanFactory的createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)由AbstractAutowireCapableBeanFactory實現。createBean方法的核心是調用了AbstractAutowireCapableBeanFactory的doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args),我們直接查看doCreateBean方法。

springboot @Value實現獲取計算機中絕對路徑文件的內容

5、我們略過創建實例的過程

直接進入applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)方法。

springboot @Value實現獲取計算機中絕對路徑文件的內容

5.1、applyMergedBeanDefinitionPostProcessors方法

主要是循環所有后置處理器對beanDefinition做處理,我們之前說過@Value注解是通過AutowiredAnnotationBeanPostProcessor來處理的,我們直接進入AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)方法如下:

springboot @Value實現獲取計算機中絕對路徑文件的內容

其中的InjectionMetadata如下,它主要封裝了bean的全限定類名和這個類中所有帶有注解的成員屬性(字段或者其他bean)描述(PropertyDescriptor,可以簡單理解為帶注解的成員屬性和注解本身兩者的組合),當然也就包括由@Value注解的字段。

springboot @Value實現獲取計算機中絕對路徑文件的內容

5.2、我們繼續進入到

findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs)方法,通過buildAutowiringMetadata(final Class<?> clazz)首先獲取了當前bean所屬類的屬性注解元數據,然后存儲到了injectionMetadataCache緩存中,完成了applyMergedBeanDefinitionPostProcessors方法。

springboot @Value實現獲取計算機中絕對路徑文件的內容

5.3、我們進入到

buildAutowiringMetadata(final Class<?> clazz)查看構建bean注入注解元數據的過程

springboot @Value實現獲取計算機中絕對路徑文件的內容

其中用到了獲取當前成員屬性AnnotationAttributes的方法findAutowiredAnnotation(AccessibleObject ao)如下:

springboot @Value實現獲取計算機中絕對路徑文件的內容

其中autowiredAnnotationTypes表示后置處理器AutowiredAnnotationBeanPostProcessor處理的注解列表,初始化如下:

springboot @Value實現獲取計算機中絕對路徑文件的內容

6、第5步完成了AbstractAutowireCapableBeanFactory

doCreateBean方法中的applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName),即完成了bean的成員屬性注解元數據的本地緩存??梢岳斫鈇pplyMergedBeanDefinitionPostProcessors為一個攔截器,即在對bean進行成員屬性和依賴注入前先預處理bean的依賴和成員屬性數據的解析和緩存,而后再進行populateBean。

6.1、進入到AbstractAutowireCapableBeanFactory

populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法,我們直接看核心代碼如下,其中postProcessProperties方法就是完成了bean的成員屬性的初始化和依賴的注入過程。

springboot @Value實現獲取計算機中絕對路徑文件的內容

6.2、因為我們要處理的是@Value和@Autowired注解的bean依賴

AutowiredAnnotationBeanPostProcessor是InstantiationAwareBeanPostProcessor接口的實現類,所以上面代碼端循環過程中會進入到之前的AutowiredAnnotationBeanPostProcessor的postProcessProperties(PropertyValues pvs, Object bean, String beanName)。

springboot @Value實現獲取計算機中絕對路徑文件的內容

6.3、上面findAutowiringMetadata方法就是第5.2步的方法

也就是從緩存Map中取出bean對應的注解元數據,而后調用InjectionMetadata的inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs)方法執行依賴注入過程。

springboot @Value實現獲取計算機中絕對路徑文件的內容

6.4、在上面對注解元數據列表循環處理(bean依賴了多個其他的bean或者多個成員屬性通過配置注入)進行依賴注入

調用element.inject(target, beanName, pvs)方法。而AutowiredAnnotationBeanPostProcessor類的內部類AutowiredFieldElement繼承了InjectionMetadata.InjectedElement類,并重寫了其inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs)方法,AutowiredAnnotationBeanPostProcessor類的內部類AutowiredMethodElement也繼承了InjectionMetadata.InjectedElement類,并重寫了其inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs)方法,因此6.3中的inject調用將會在此子類中執行,AutowiredFieldElement處理成員屬性上注解,AutowiredMethodElement處理方法上注解。因此@Value注解的處理將會進入到AutowiredFieldElement的inject方法。

springboot @Value實現獲取計算機中絕對路徑文件的內容

6.5、首先通過beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter)方法解析依賴

然后注冊當前bean依賴的其他bean,最后通過反射將依賴注入到當前bean中完成bean的依賴注入過程。DefaultListableBeanFactory繼承了AbstractAutowireCapableBeanFactory類,我們先查看DefaultListableBeanFactory的resolveDependency方法,其中主要是調用了DefaultListableBeanFactory的doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter)方法,我們直接看doResolveDependency方法。

springboot @Value實現獲取計算機中絕對路徑文件的內容

6.6、以上解析@Value注解

getSuggestedValue返回的值就是${xxx.documentcenter.bucketName:ssdocumentcenterstatic},因為是字符串,所以進入到下面的邏輯AbstractBeanFactory的resolveEmbeddedValue(@Nullable String value)方法中。resolveEmbeddedValue將完成@Value注解值的解析過程,最終得到配置文件中配置的值ssdocumentcenterstatic。下面的TypeConverter的convertIfNecessary主要完成數據類型的轉換,比如配置文件中配置的Boolean類型,將String轉為Boolean等。最后返回value值并注入到bean中,此成員屬性注入到bean的過程就完成了。我們簡單看一下resolveEmbeddedValue解析過程,主要通過AbstractPropertyResolver解析器完成,其內部使用了默認的占位符如下:

springboot @Value實現獲取計算機中絕對路徑文件的內容

通過其doResolvePlaceholders(String text, PropertyPlaceholderHelper helper)方法完成解析,內部調用了PropertyPlaceholderHelper的parseStringValue(String value, PlaceholderResolver placeholderResolver, Set visitedPlaceholders)方法來具體實現注解的值的解析和占位替換。解析首先是從配置文件對應的PropertySource中完成配置和值讀取,最終通過MapPropertySource實現。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://www.cnblogs.com/mysgk/p/9427282.html

延伸 · 閱讀

精彩推薦
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

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

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

    spcoder14552021-10-18
  • Java教程小米推送Java代碼

    小米推送Java代碼

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

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

    Java使用SAX解析xml的示例

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

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

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

    Java教程網2942020-09-17
  • Java教程20個非常實用的Java程序代碼片段

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

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

    lijiao5352020-04-06
  • Java教程升級IDEA后Lombok不能使用的解決方法

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

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

    程序猿DD9332021-10-08
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

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

    littleschemer13532021-05-16
  • Java教程Java8中Stream使用的一個注意事項

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

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

    阿杜7482021-02-04
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 九色在线视频 | 日韩欧美专区 | 中文字幕视频在线 | 亚洲精选久久 | 亚洲高清毛片一区二区 | 成人在线免费小视频 | 国产片性视频免费播放 | 国内精品久久久久久影视8 有码在线 | 久久免费99精品久久久久久 | 久久精品视频一区 | 亚洲色图综合 | 国产精品免费久久久久久久久 | 久久国产高清 | 国产精品久久久久久吹潮 | 一区二区三区久久 | 日韩中文字幕电影 | 91久久综合 | 欧美三区| 韩国精品一区 | 黄色片子免费观看 | 免费日韩精品 | 天天干人人| 成年免费视频黄网站在线观看 | 国产一区二区在线播放 | 五月天婷婷综合 | av电影在线免费 | 成人在线播放 | 91精品久久久久久久久久入口 | 一级片在线观看 | 国产精品视频一区二区三区不卡 | 中文字幕一区二区三区乱码图片 | 在线观看国产精品一区 | 欧美在线99 | 久久综合一 | 亚洲成人免费在线 | 一区二区三区在线视频播放 | 日韩激情一区 | 欧美一级黄色片 | 国产日韩欧美不卡 | 人人超碰免费 | 亚洲 中文 欧美 日韩 在线观看 |