人妻系列无码专区av在线,国内精品久久久久久婷婷,久草视频在线播放,精品国产线拍大陆久久尤物

當前位置:首頁 > 軟件開發(fā) > 正文

throwable exception?SpringBoot是如何動起來的

throwable exception?SpringBoot是如何動起來的

各位老鐵們好,相信很多人對throwable exception都不是特別的了解,因此呢,今天就來為大家分享下關于throwable exception以及Spring...

各位老鐵們好,相信很多人對throwable exception都不是特別的了解,因此呢,今天就來為大家分享下關于throwable exception以及SpringBoot是如何動起來的的問題知識,還望可以幫助大家,解決大家的一些困惑,下面一起來看看吧!

java web項目中如何優(yōu)雅的處理異常

如果Java方法不能按照正常的流程執(zhí)行,那么可以通過另外一種途徑退出:拋出一個封裝了錯誤信息的對象,這個就是Java的異常;當發(fā)生異常時,后面的代碼無法繼續(xù)執(zhí)行,而是由異常處理器繼續(xù)執(zhí)行。

01.異常的分類

Throwable是所有異常的超類,下一級可以分為Error和Exception:

1.Error

Error是指Java運行時系統(tǒng)內部的錯誤,或者說它代表了JVM本身的錯誤,通常都是比較嚴重的錯誤,比如內存溢出,虛擬機錯誤等等;

Error通常和硬件或JVM有關,和程序本身無關,所以不能被代碼捕獲和處理。

2.Exception

我們經常說的異常是指Exception,又可以分成運行時異常和檢查異常。

RuntimeException:運行時異常,這類異常在編譯期間不強制代碼捕捉,但是可能在在JVM運行期間拋出異常;出現此類異常,通常是代碼的問題,所以需要修改程序避免這類異常。常見的運行時異常,比如:NullPointerException、ClassCastException等等。

CheckedException:檢查異常,這種異常發(fā)生在編譯階段,Java編譯器會強制代碼去捕獲和處理此類異常;比如:ClassNotFoundException、IllegalAccessException等等。

02.異常的處理方法

捕獲異常使用try...catch語句,把可能發(fā)生異常的代碼放到try{...}中,然后使用catch捕獲對應的異常;

我們也可以在代碼塊中使用Throw向上級代碼拋出異常;

在方法中使用throws關鍵字,向上級代碼拋出異常;

03.Throw和throws的區(qū)別

Throw在方法內,后面跟著異常對象;而throws是用在方法上,后面跟異常類;

Throw會拋出具體的異常對象,當執(zhí)行到Throw的時候,方法內的代碼也就執(zhí)行結束了;throws用來聲明異常,提醒調用方這個方法可能會出現這種異常,請做好處理的準備,但是不一定會真的出現異常。

04.如何優(yōu)雅地處理異常

不要試圖通過異常來控制程序流程,比如開發(fā)一個接口,正確的做法是對入參進行非空驗證,當參數為空的時候返回“參數不允許為空”,而不應該捕捉到空指針的時候返回錯誤提示。

僅捕獲有必要的代碼,盡量不要用一個try...catch包住大段甚至整個方法內所有的代碼,因為這樣會影響JVM對代碼進行優(yōu)化,從而帶來額外的性能開銷。

很多程序員喜歡catch(Exceptione),其實應該盡可能地精確地指出是什么異常。

不要忽略異常,捕捉到異常之后千萬不能什么也不做,要么在catch{...}中輸出異常信息,要么通過Throw或throws拋出異常,讓上層代碼處理。

盡量不要在catch{...}中輸出異常后,又向上層代碼拋出異常,因為這樣會輸出多條異常信息,而且它們還是相同的,這樣可能會產生誤導。

不要在finally{...}中寫return,因為try{...}在執(zhí)行return之前執(zhí)行finally{...},如果finally{...}中有return,那么將不再執(zhí)行try{...}中的return。

我將持續(xù)分享Java開發(fā)、架構設計、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關注。

SpringBoot是如何動起來的

程序入口

SpringApplication.run(BeautyApplication.class,args);

執(zhí)行此方法來加載整個SpringBoot的環(huán)境。

1.從哪兒開始?

SpringApplication.java

/**

*RuntheSpringapplication,creatingandrefreshinganew

*{@linkApplicationContext}.

*@paramargstheapplicationarguments(usuallypassedfromaJavamainmethod)

*@returnarunning{@linkApplicationContext}

*/

publicConfigurableApplicationContextrun(String...args){

//...

}

調用SpringApplication.java中的run方法,目的是加載SpringApplication,同時返回ApplicationContext。

2.執(zhí)行了什么?

2.1計時

記錄整個SpringApplication的加載時間!

StopWatchstopWatch=newStopWatch();

stopWatch.start();

//...

stopWatch.stop();

if(this.logStartupInfo){

newStartupInfoLogger(this.mainApplicationClass)

.logStarted(getApplicationLog(),stopWatch);

}

2.2聲明

指定java.awt.headless,默認是true一般是在程序開始激活headless模式,告訴程序,現在你要工作在Headlessmode下,就不要指望硬件幫忙了,你得自力更生,依靠系統(tǒng)的計算能力模擬出這些特性來。

privatevoidconfigureHeadlessProperty(){

System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,System.getProperty(

SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,Boolean.toString(this.headless)));

}

2.4配置監(jiān)聽并發(fā)布應用啟動事件

SpringApplicationRunListener負責加載ApplicationListener事件。

SpringApplicationRunListenerslisteners=getRunListeners(args);

//開始

listeners.starting();

//處理所有propertysources配置和profiles配置,準備環(huán)境,分為標準Servlet環(huán)境和標準環(huán)境

ConfigurableEnvironmentenvironment=prepareEnvironment(listeners,applicationArguments);

//準備應用上下文

prepareContext(context,environment,listeners,applicationArguments,printedBanner);

//完成

listeners.started(context);

//異常

handleRunFailure(context,ex,exceptionReporters,listeners);

//執(zhí)行

listeners.running(context);

getRunListeners中根據type=SpringApplicationRunListener.class去拿到了所有的Listener并根據優(yōu)先級排序。

對應的就是META-INF/spring.factories文件中的org.springframework.boot.SpringApplicationRunListener=org.springframework.boot.context.event.EventPublishingRunListener

private<T>Collection<T>getSpringFactoriesInstances(Class<T>type,

Class<?>[]parameterTypes,Object...args){

ClassLoaderclassLoader=Thread.currentThread().getContextClassLoader();

//Usenamesandensureuniquetoprotectagainstduplicates

Set<String>names=newLinkedHashSet<>(

SpringFactoriesLoader.loadFactoryNames(type,classLoader));

List<T>instances=createSpringFactoriesInstances(type,parameterTypes,

classLoader,args,names);

AnnotationAwareOrderComparator.sort(instances);

returninstances;

}

復制代碼

在ApplicationListener中,可以針對任何一個階段插入處理代碼。

publicinterfaceSpringApplicationRunListener{

/**

*Calledimmediatelywhentherunmethodhasfirststarted.Canbeusedforvery

*earlyinitialization.

*/

voidstarting();

/**

*Calledoncetheenvironmenthasbeenprepared,butbeforethe

*{@linkApplicationContext}hasbeencreated.

*@paramenvironmenttheenvironment

*/

voidenvironmentPrepared(ConfigurableEnvironmentenvironment);

/**

*Calledoncethe{@linkApplicationContext}hasbeencreatedandprepared,but

*beforesourceshavebeenloaded.

*@paramcontexttheapplicationcontext

*/

voidcontextPrepared(ConfigurableApplicationContextcontext);

/**

*Calledoncetheapplicationcontexthasbeenloadedbutbeforeithasbeen

*refreshed.

*@paramcontexttheapplicationcontext

*/

voidcontextLoaded(ConfigurableApplicationContextcontext);

/**

*Thecontexthasbeenrefreshedandtheapplicationhasstartedbut

*{@linkCommandLineRunnerCommandLineRunners}and{@linkApplicationRunner

*ApplicationRunners}havenotbeencalled.

*@paramcontexttheapplicationcontext.

*@since2.0.0

*/

voidstarted(ConfigurableApplicationContextcontext);

/**

*Calledimmediatelybeforetherunmethodfinishes,whentheapplicationcontexthas

*beenrefreshedandall{@linkCommandLineRunnerCommandLineRunners}and

*{@linkApplicationRunnerApplicationRunners}havebeencalled.

*@paramcontexttheapplicationcontext.

*@since2.0.0

*/

voidrunning(ConfigurableApplicationContextcontext);

/**

*Calledwhenafailureoccurswhenrunningtheapplication.

*@paramcontexttheapplicationcontextor{@codenull}ifafailureoccurredbefore

*thecontextwascreated

*@paramexceptionthefailure

*@since2.0.0

*/

voidfailed(ConfigurableApplicationContextcontext,Throwableexception);

}

3.每個階段執(zhí)行的內容

3.1listeners.starting();

在加載SpringApplication之前執(zhí)行,所有資源和環(huán)境未被加載。

3.2prepareEnvironment(listeners,applicationArguments);

創(chuàng)建ConfigurableEnvironment;將配置的環(huán)境綁定到SpringApplication中;

privateConfigurableEnvironmentprepareEnvironment(

SpringApplicationRunListenerslisteners,

ApplicationArgumentsapplicationArguments){

//Createandconfiguretheenvironment

ConfigurableEnvironmentenvironment=getOrCreateEnvironment();

configureEnvironment(environment,applicationArguments.getSourceArgs());

listeners.environmentPrepared(environment);

bindToSpringApplication(environment);

if(this.webApplicationType==WebApplicationType.NONE){

environment=newEnvironmentConverter(getClassLoader())

.convertToStandardEnvironmentIfNecessary(environment);

}

ConfigurationPropertySources.attach(environment);

returnenvironment;

}

3.3prepareContext

配置忽略的Bean;

privatevoidconfigureIgnoreBeanInfo(ConfigurableEnvironmentenvironment){

if(System.getProperty(

CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME)==null){

Booleanignore=environment.getProperty("spring.beaninfo.ignore",

Boolean.class,Boolean.TRUE);

System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME,

ignore.toString());

}

}

打印日志-加載的資源

BannerprintedBanner=printBanner(environment);

根據不同的WebApplicationType創(chuàng)建Context

context=createApplicationContext();

3.4refreshContext

支持定制刷新

/**

*RegisterashutdownhookwiththeJVMruntime,closingthiscontext

*onJVMshutdownunlessithasalreadybeenclosedatthattime.

*<p>Thismethodcanbecalledmultipletimes.Onlyoneshutdownhook

*(atmax)willberegisteredforeachcontextinstance.

*@seejava.lang.Runtime#addShutdownHook

*@see#close()

*/

voidregisterShutdownHook();

3.5afterRefresh

刷新后的實現方法暫未實現

/**

*Calledafterthecontexthasbeenrefreshed.

*@paramcontexttheapplicationcontext

*@paramargstheapplicationarguments

*/

protectedvoidafterRefresh(ConfigurableApplicationContextcontext,

ApplicationArgumentsargs){

}

3.6listeners.started(context);

到此為止,SpringApplication的環(huán)境和資源都加載完畢了;發(fā)布應用上下文啟動完成事件;執(zhí)行所有Runner運行器-執(zhí)行所有ApplicationRunner和CommandLineRunner這兩種運行器

//啟動

callRunners(context,applicationArguments);

3.7listeners.running(context);

觸發(fā)所有SpringApplicationRunListener監(jiān)聽器的running事件方法

希望對你有幫助

好了,關于throwable exception和SpringBoot是如何動起來的的問題到這里結束啦,希望可以解決您的問題哈!