您好,登錄后才能下訂單哦!
這篇文章主要介紹“springboot2.0.6的運(yùn)行流程以及怎么執(zhí)行SpringApplication的run方法”,在日常操作中,相信很多人在springboot2.0.6的運(yùn)行流程以及怎么執(zhí)行SpringApplication的run方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”springboot2.0.6的運(yùn)行流程以及怎么執(zhí)行SpringApplication的run方法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
設(shè)置resourceload
設(shè)置primarySources,可以把啟動(dòng)類加載進(jìn)入spring容器
判斷當(dāng)前application應(yīng)該運(yùn)行在什么環(huán)境下,即獲取webApplicationType(程序應(yīng)用類型)
加載所有classpath下面的META-INF/spring.factories中的ApplicationContextInitializer
加載所有classpath下面的META-INF/spring.factories中的ApplicationListener
mainApplicationClass:找出main方法啟動(dòng)的class
加載所有classpath下面的META-INF/spring.factories文件,獲取SpringApplicationRunListener的集合,即加載所有spring.factories文件中SpringApplicationRunListener
依次調(diào)用的SpringApplicationRunListener的starting方法,最終調(diào)用ApplicationListener的onApplicationEvent方法,發(fā)布springboot啟動(dòng)事件
ConfigurableEnvironment:代表兩種意義:一種是profiles,用來描述哪些bean definitions是可用的;一種是properties,用來描述系統(tǒng)的配置,其來源可能是配置文件、JVM屬性文件、操作系統(tǒng)環(huán)境變量等等
創(chuàng)建ConfigurableEnvironment,即執(zhí)行g(shù)etOrCreateEnvironment()方法,根據(jù)webApplicationType創(chuàng)建不同的Environment對象
配置environment,即執(zhí)行configureEnvironment(XX)方法。主要把運(yùn)行方法參數(shù)配置到environment
通過configurePropertySources(environment, args)設(shè)置properties
通過configureProfiles(environment, args)設(shè)置profiles
執(zhí)行l(wèi)isteners.environmentPrepared(environment)方法,發(fā)布environmentPrepared事件,即調(diào)用ApplicationListener的onApplicationEvent事件
執(zhí)行bindToSpringApplication方法,即把當(dāng)前的environment和當(dāng)前的springApplication綁定
如果不是web環(huán)境,但是是web的environment,則把其轉(zhuǎn)換成標(biāo)準(zhǔn)的environment
執(zhí)行ConfigurationPropertySources.attach(environment)方法,將ConfigurationPropertySource放入environment的propertysource中的第一個(gè)
根據(jù)不同的webApplicationType設(shè)置不同的contextClass(容器的class類型),然后生成不同的容器實(shí)例對象
生成容器實(shí)例的時(shí)候,對于Kotlin類使用'primary'構(gòu)造函數(shù)實(shí)例化一個(gè)類,如果不是就使用默認(rèn)構(gòu)造函數(shù),根據(jù)得到構(gòu)造函數(shù)生成實(shí)例對象,如果構(gòu)造函數(shù)不是公共的,我們嘗試去改變并訪問
執(zhí)行context.setEnvironment(environment)方法,設(shè)置spring容器的environment
執(zhí)行postProcessApplicationContext(context)方法,設(shè)置beanNameGenerator(其不未空時(shí)注入到容器中)和resourceLoader(其不未空時(shí)加載對象)
執(zhí)行applyInitializers(context),回調(diào)所有ApplicationContextInitializer的initialize來初始化context,其中還檢測各個(gè)ApplicationContextInitializer是否接受該類型的容器
執(zhí)行l(wèi)isteners.contextPrepared(context),調(diào)用SpringApplicationRunListener的contextPrepared方法,但目前是個(gè)空實(shí)現(xiàn)。
依次向容器注冊springApplicationArguments和springBootBanner這兩個(gè)bean
getAllSources就是獲取我們的primarySources和sources
加載所有資源到context里,即調(diào)用load(context, sources.toArray(new Object[0]))方法創(chuàng)建BeanDefinitionLoader,設(shè)置該loader的sources,annotatedReader,xmlReader,scanner,以及添加scanner的ExcludeFilter(即過濾springboot的啟動(dòng)類),若用戶啟動(dòng)的時(shí)候設(shè)置了beanNameGenerator,resourceLoader,environment的話就替代我們自身設(shè)置的屬性。同時(shí)根據(jù)source的類型選擇不同的load方法,這邊我們是load(class),最終判斷是否是component注解,是的話就通過annotatedReader將啟動(dòng)類注冊成bean
執(zhí)行l(wèi)isteners.contextLoaded(context)方法,判斷ApplicationListener是否屬于ApplicationContextAware,如果是的話就將spring容器賦值給該listener,然后將該ApplicationListener賦值給spring容器,然后調(diào)用ApplicationListener的onApplicationEvent方法
執(zhí)行prepareRefresh()方法設(shè)置些初始的操作。比如 開啟激活,啟動(dòng)日期,初始化propertySource。
獲取beanFactory
執(zhí)行prepareBeanFactory(beanFactory),設(shè)置beanFactory的classloader,BeanExpressionResolver,PropertyEditorRegistrar, ApplicationContextAwareProcessor和忽略xxxxAware,注冊依賴,還有ApplicationListenerDetector
自動(dòng)注入不是指的@AutoWire 而是指的是beans的default-autowire="byType" 或在bean的autowire="byType" ,這樣spring 會(huì)去ioc容器尋找類型相似的類型給其注入,如果實(shí)現(xiàn)了spring 的xxaware接口,就不會(huì)自動(dòng)注入記載filterPropertyDescriptorsForDependencyCheck刪除與入?yún)㈩愋拖嗤膶傩?/p>
ApplicationContextAwareProcessor:只是將applicationContext傳遞給ApplicationContextAwareProcessor,方便后面的xxxAware調(diào)用
忽略xxxxAware:忽略這些Aware接口實(shí)現(xiàn)類中與接口set方法中入?yún)㈩愋拖嗤膶傩缘牡淖詣?dòng)注入這樣就保證了關(guān)鍵的類是由spring容器自己產(chǎn)生的而不是我們注入的
注冊依賴:即指定一些類自動(dòng)注入的實(shí)例是spring指定的實(shí)例對象
ApplicationListenerDetector:檢測實(shí)現(xiàn)了ApplicationListener的實(shí)現(xiàn)類,因?yàn)橛行?shí)現(xiàn)類,無法通過getBeanNamesForType獲取到。
執(zhí)行postProcessBeanFactory(beanFactory)方法,設(shè)置ignoreDependencyInterface(ServletContextAware)還有annotatedClasses,basePackages如果存在就設(shè)置。
執(zhí)行invokeBeanFactoryPostProcessors(beanFactory)方法,從beanFactoryPostProcessors獲取BeanFactoryPostProcessor,然后先執(zhí)行BeanDefinitionRegistryPostProcessor類型的postProcessBeanDefinitionRegistry,繼續(xù)從beanFactory獲取BeanDefinitionRegistryPostProcessor類型的bean然后執(zhí)行postProcessBeanDefinitionRegistry,執(zhí)行的過程按照PriorityOrdered,Ordered,普通的類型進(jìn)行執(zhí)行,然后優(yōu)先執(zhí)行registryProcessors的postProcessBeanFactory在執(zhí)行regularPostProcessors的postProcessBeanFactory,再從BeanFactory獲取PriorityOrdered,Ordered,普通的類型三種類型的BeanFactoryPostProcessor,并按照順序執(zhí)行??偨Y(jié):從之前加入的beanFactoryPostProcessor先執(zhí)行postProcessBeanDefinitionRegistry(假如是BeanDefinitionRegistryPostProcessor)然后在執(zhí)行postProcessBeanFactory方法,然后從beanFactory獲取BeanFactoryPostProcessor 然后執(zhí)行postProcessBeanFactory,執(zhí)行過程中都要按照PriorityOrdered,Ordered,普通的類型三種類型的順序執(zhí)行。
執(zhí)行egisterBeanPostProcessors方法,從beanFactory獲取BeanPostProcessor分別按照PriorityOrdered,Ordered,普通的類型注冊BeanPostProcessor
BeanPostProcessor和BeanFactoryPostProcessor:前者是對bean初始化前后進(jìn)行設(shè)置,后者可以對beanFactory進(jìn)行修改 或者,可以對beanDefinition進(jìn)行修改或者增加或者初始化渴望提前初始化的bean
執(zhí)行initMessageSource()方法,初始化我們國際化文件
執(zhí)行initApplicationEventMulticaster()方法,設(shè)置applicationEventMulticaster,spring發(fā)布各種事件就依靠他,這個(gè)和springboot發(fā)布事件使用相同的類
執(zhí)行onRefresh()方法,初始化其他的子容器類中的bean,同時(shí)創(chuàng)建spring的內(nèi)置容器(tomcat)
執(zhí)行registerListeners()方法,添加用戶設(shè)置applicationListeners,然后從beanFactory獲取ApplicationListener,然后發(fā)布需要earlyApplicationEvents事件
執(zhí)行inishBeanFactoryInitialization(beanFactory)方法,實(shí)例化非懶加載的剩余bean
執(zhí)行finishRefresh方法,清理資源緩存,初始化lifecycle,調(diào)用lifecycle的onrefresh,發(fā)布ContextRefreshedEvent的事件,激活JMX,啟動(dòng)tomcat
注冊一個(gè)線程,該線程主要指向doclose方法,doClose方法的邏輯就是:從applicationContexts集合中刪除當(dāng)前容器,MBeanServer卸載MBean,發(fā)布容器關(guān)閉事件,調(diào)用了實(shí)現(xiàn)了lifecycleProcessor接口的bean,destroyBeans,closeBeanFactory,onClose:關(guān)閉內(nèi)置tomcat,active設(shè)置為false
從spring容器中獲取ApplicationRunner和CommandLineRunner對象,然后按照順序排序,循環(huán)調(diào)用他們的run方法
處理不同的異常狀態(tài),然后調(diào)用listeners.failed(context, exception),并關(guān)閉spring容器
發(fā)布running事件
該配置模塊的主要使用到了SpringFactoriesLoader,即Spring工廠加載器,該對象提供了loadFactoryNames方法,入?yún)閒actoryClass和classLoader,即需要傳入上圖中的工廠類名稱和對應(yīng)的類加載器,方法會(huì)根據(jù)指定的classLoader,加載該類加器搜索路徑下的指定文件,即spring.factories文件,傳入的工廠類為接口,而文件中對應(yīng)的類則是接口的實(shí)現(xiàn)類,或最終作為實(shí)現(xiàn)類,所以文件中一般為一對多的類名集合,獲取到這些實(shí)現(xiàn)類的類名后,loadFactoryNames方法返回類名集合,方法調(diào)用方得到這些集合后,再通過反射獲取這些類的類對象、構(gòu)造方法,最終生成實(shí)例
到此,關(guān)于“springboot2.0.6的運(yùn)行流程以及怎么執(zhí)行SpringApplication的run方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。