SpringBoot中Spring應(yīng)用上下文的準(zhǔn)備有哪些

SpringBoot中Spring應(yīng)用上下文的準(zhǔn)備有哪些,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)建站是一家集網(wǎng)站建設(shè),元寶企業(yè)網(wǎng)站建設(shè),元寶品牌網(wǎng)站建設(shè),網(wǎng)站定制,元寶網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,元寶網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

Spring應(yīng)用上下文的準(zhǔn)備

首先,通過圖 4-4 來整體了解一下 prepareContext 的核心功能及流程。

SpringBoot中Spring應(yīng)用上下文的準(zhǔn)備有哪些

配合流程圖,看一下 SpringApplication 中 prepareContext 方法源代碼及功能注解。

private void prepareContext(ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunL isteners listeners , Applicat ionArguments applicat ionArguments, Bann er printedBanner) { //沒置上下文的配置環(huán)境 context . setEnvironment (environment); //應(yīng)用上下文后置處理 postProcessApplicationContext( context);//在 context 刷新之前,Appl icat ionContext Init ial izer 初始化 context applyInitializers(context); //通知監(jiān)聽器 context 準(zhǔn)備完成,該方法以 上為上下文準(zhǔn)備階段,以下為上下文加載階段 listeners . contextPrepared(context);//打印日志,啟動 Profile if (this . logStartupInfo)- logStartupInfo(context . getParent() == nu1l); logStartupProfileInfo( context); } //獲得 ConfigurableL istableBeanFactory 并炷冊單例對象 ConfigurableL istableBeanFactory beanFactory = context . getBeanFactory(); beanFactory. registerSingleton("springApplicat ionArguments", applicationAr guments); if (printedBanner != null) { //注冊打印日志對象 beanF actory. registerSingleton("springBootBanner", printedBanner); if (beanFactory instanceof DefaultlistableBeanFactory) { //沒置是否允許覆蓋炷冊 ((DefaultListableBeanFactory) beanFactory) . setAllowBeanDefinitionOverriding(this . allowBeanDefinitionOverriding); //獲取全部配置源,其中包含 primarySources 和 sources Set<0bject> sources = getAllSources(); Assert . notEmpty(sources, "Sources must not be empty"); //將 sources 中的 Bean 加載到 context 中 load(context, sources . toArray(new 0bject[0])); //遁知監(jiān)聽器 context 加載完成 listeners . contextLoaded(context); }

通過流程圖和具體代碼可以看出,在該方法內(nèi)完成了兩步操作:應(yīng)用上下文的準(zhǔn)備和加載。

下面我們針對具體的源代碼進行詳細講解。

應(yīng)用上下文準(zhǔn)備階段

在上下文準(zhǔn)備階段,主要有 3 步操作:對 context 設(shè) 置 environment、應(yīng)用上下文后置處理和  ApplicationContextlnitializer 初始化 context 操作。

首先是對 context 設(shè)置 environment,代碼和業(yè)務(wù)操作都很簡單。

public void setEnvironment (ConfigurableEnvironment environment) { //設(shè)置 context 的 environment super. setEnvi ronment( environment); //設(shè)置 context 的 reader 屬性的 conditionEvaluator 屬性 this.reade er. settEnvironment(environment) ; //設(shè)置 context 的 scanner 屬性的 environment 屬性 this. scanner. setEnvi ronment ( envi ronment); }

隨 后 , 便 是 進 行 Spring 應(yīng) 用 上 下 文 的 后置處理 , 這 一 步 是 通  過postProcessApplicationContext 方法來完成的。

protected void postProcessApplicat ionContext (ConfigurableApplicat ionConEext context){ f (this. beanNameGenerator != null) { // 如果 beanNameGenerator 為 null, 則將當(dāng)前的 beanNameGenerator 按照默認名字進 行注冊 context . getBeanFactory(). regi sterSingleton( Annotat ionConfigUtils .CONF IGURATION BEAN NAME GENERATOR, this . beanNameGenerator); esourceLoader 為 null 時, 則根據(jù) context 的類型分別進行 Resourceloader 和 CL assLoader 的設(shè)置 if (this .resourceLoader != null) { F (context instanceof GenericApplicationContext) { ((GenericApplicationContext) context) . setResourcel oader(this . resource Loader); if (context instanceof DefaultResourceLoader) { ( (DefaultResourceLoader) context) . setClassLoader(this.resourceLoader. getClassLoader()); //如果為 true 則獲取并沒置轉(zhuǎn)換服務(wù) f (this .addConversionService) { context . getBeanFactory(). setConversionService( ApplicationConversionService . getSharedInstance()); }

postProcessApplicationContext 方 法 主 要 完 成 上 下 文 的 后 置 操 作 , 默 認 包  含beanNameGeneratorResourceL oader.ClassL oader 和 ConversionService  的設(shè)置。該方法可由子類覆蓋實現(xiàn),以添加更多的操作。

而在此階段,beanNameGenerator 和 resourceL oader 都為 null,因此只操作了最后-一步的設(shè)置轉(zhuǎn)換服務(wù)。

最后,在通知監(jiān)聽器 context 準(zhǔn)備完成之前,通過 applylnitializers 方法對上下文進行初始化。

所使用的 ApplicationContextInitializer 正是我們在 SpringApplication 初始化階段設(shè)置在itializers  變量中的值,只不過在通過 getlnitializers 方法獲取時進行了去重和排序。

protected void applyInitializers(ConfigurableApplicat ionContext context) { /獲取 Appl icat ionContextInitializer 集合并遍歷 for (ApplicationContextInitializer initializer : getInitializers()) { //解析當(dāng)前 initial izer.實現(xiàn)的 Appl icat ionContextInitializer 的泛型參數(shù) Class<?> requiredType = GenericTypeResolver . resolveTypeArgument( initializer . getClass(), ApplicationContextInitializer.class); 1 斷言判斷所需類似是否與 context 類型匹配 Assert. isInstanceOf(requiredType, context, "Unable to call initialize r."); // 初始化 context initializer. initialize(context); } }

完成以上操作之后,程序便調(diào)用 SpringApplicationRunListeners 的 contextPrepared  方法通知監(jiān)聽器,至此第一階段的準(zhǔn)備操作完成。

應(yīng)用上下文加載階段

應(yīng)用上下文加載階段包含以下步驟:打印日志和 Profile 的設(shè)置、設(shè)置是否允許覆蓋注冊、獲取全部配置源、將配置源加載入上下文、通知監(jiān)控器 contex  加載完成。

首先進入應(yīng)用上下文加載階段的操作為打印日志和 Profile 的設(shè)置,對此不展開講解。隨后,便是獲得 ConfigurableL  istableBeanFactory 并注冊單例對象,注冊的單例對象包含:

ApplicationArguments 和 Banner。 當(dāng) BeanFactory 為 DefaultL istableBeanFactory  時,進入設(shè)置是否允許覆蓋注冊的處理邏輯。

此處需注意的是,當(dāng)進行了 ApplicationArguments 類單例對象的注冊之后,也就意味著我們在使用 Spring  應(yīng)用上下文的過程中可以通過依賴注入來使用該對象。

@Resource private ApplicationArguments applicat ionArguments;

完成以.上操作后,便進入配置源信息的處理階段,這一步通過 getAllSources 方法來對配置源信息進行合并操作。

public Set<Object> getAllSources() { Set<0bject> allSources = new LinkedHashSet<>(); if (!CollectionUtils.isEmpty(this . primarySources)) { allSources.addAll(this.primarySources); if (!CollectionUtils . isEmpty(this. sources)) { allSources. addAll(this.sources); } }

return Collections . unmodifiableSet(allSources); }以上操作邏輯很簡單,如果 Set  集合中不存在 primarySources 配置源或 sources 配置源,則將其添加入 Set 中,同時將 Set 設(shè)置為不可修改,并返回。

前面章節(jié)已經(jīng)提到,變量 primarySources 的值 來自 SpringApplication 的構(gòu)造參數(shù),變量sources 的值來自  setResources 方法。

當(dāng)獲得所有的配置源信息之后,通過 load 方法將配置源信息加載到上下文中,代碼如下。

protected void load(ApplicationContext context, Object[] sources) { /日志打印 BeanDefinitionLoader loader = createBeanDefinitionLoader( getBeanDefinitionRegistry(context), sources); f (this. beanNameGenerator != nu1l). loader. setBeanNameGenerator(this . beanNameGenerator); if (this.resourceLoader != nu1l) { loader . setResourceLoader(this . resourceLoader); if (this. environment != null) { loader . setEnvironment (this . environment) ; loader. load(); }

該方法主要通過 BeanDefinitionL oader  來完成配置資源的加載操作。我們進一步查看方法createBeanDefinitionL oader 的源代碼,會發(fā)現(xiàn)它最終調(diào)用了 BeanDefinitionL  oader 的構(gòu)造方法,并進行初始化操作。

BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) { this. sources = sources; this . annotatedReader = new AnnotatedBeanDefinitionReader(registry); this . xmlReader = new XmlBeanDefinitionReader(registry); if (isGroovyPresent()) this. groovyReader = new GroovyBeanDefinitionReader(registry); }

通過 BeanDefinitionLoader  的構(gòu)造方法我們可以看到 BeanDefinitionLoader  支持基于AnnotatedBeanDefinitionReaderXmlBeanDefinitionReader、GroovyBeanDefinitionReader等  多種類型的加載操作。

在執(zhí)行完 BeanDefinitionL oader 的創(chuàng)建及基本屬性設(shè)置之后,調(diào)用其  load方法,該方法最終執(zhí)行以下代碼。

private int load(0bject source) { Assert. notNull(source, "Source must not be null"); if (source instanceof Class<?>) { return load((Class<?>) source); }if (source instanceof Resource) return load( (Resource) source); } if (source instanceof Package) { return load( (Package) source); } if (source instanceof CharSequence) { return load( (CharSequence) source); throw new IllegalArgumentException("Invalid source type ”+ source. getC lass());}

從以上代碼可以看出,BeanDefinitionLoader 加載支持的范圍包括:

Class、Resource、 Package 和 CharSequence 四種。 前面我們已經(jīng)提到變量 sources的來源有  primarySources 配置源和 sources 配置源。變量 primarySources 在初始化時接收的類型為 Class,而變量 sources  通過 set(Set )方法接收的參數(shù)為 String 集合。

因此,在實際使用的過程中,Resource 和 Package  的判斷分支始終無法進入執(zhí)行階段。

完成以上操作后,接下來執(zhí)行 SpringApplicationRunListeners 的 contextL  oaded 方法通知監(jiān)聽器上下文加載完成,至此整個 Spring 應(yīng)用上下文的準(zhǔn)備階段完成。

關(guān)于SpringBoot中Spring應(yīng)用上下文的準(zhǔn)備有哪些問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

本文題目:SpringBoot中Spring應(yīng)用上下文的準(zhǔn)備有哪些
網(wǎng)頁URL:http://muchs.cn/article40/jpiheo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)站內(nèi)鏈、網(wǎng)站設(shè)計、響應(yīng)式網(wǎng)站、網(wǎng)站收錄、動態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化