springboot 源碼理解
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
66套java從入門到精通實(shí)戰(zhàn)課程分享
package?com.example.demo;
?
import?org.springframework.boot.SpringApplication;
import?org.springframework.boot.autoconfigure.SpringBootApplication;
?
@SpringBootApplication
public?class?DemoApplication?{
?
?public?static?void?main(String[]?args)?{
?
??SpringApplication.run(DemoApplication.class,args);
?}
}
????/**
??*?Static?helper?that?can?be?used?to?run?a?{@link?SpringApplication}?from?the
??*?specified?sources?using?default?settings?and?user?supplied?arguments.
??*?@param?primarySources?the?primary?sources?to?load
??*?@param?args?the?application?arguments?(usually?passed?from?a?Java?main?method)
??*?@return?the?running?{@link?ApplicationContext}
??*/
?public?static?ConfigurableApplicationContext?run(Class>[]?primarySources,?String[]?args)?{
??return?new?SpringApplication(primarySources).run(args);
?}
public?SpringApplication(ResourceLoader?resourceLoader,?Class>...?primarySources)?{
??
????????//?默認(rèn)為null
????????this.resourceLoader?=?resourceLoader;
??Assert.notNull(primarySources,?"PrimarySources?must?not?be?null");
????????//?1.?初始化主的資源
??this.primarySources?=?new?LinkedHashSet<>(Arrays.asList(primarySources));
????????//?2.?推斷應(yīng)用類型?
??this.webApplicationType?=?WebApplicationType.deduceFromClasspath();
????????//?3.?初始化所有實(shí)現(xiàn)?ApplicationContextInitializer的子類
??setInitializers((Collection)?getSpringFactoriesInstances(ApplicationContextInitializer.class));
????????//?4.?初始化所有的實(shí)現(xiàn)ApplicationListener?的監(jiān)聽器,過程和3中的邏輯是一樣的
??setListeners((Collection)?getSpringFactoriesInstances(ApplicationListener.class));
????????//?5.?獲取mian方法??(這塊的思路比較好,以下會有介紹)
??this.mainApplicationClass?=?deduceMainApplicationClass();
?}
private??Collection ?getSpringFactoriesInstances(Class ?type)?{
??return?getSpringFactoriesInstances(type,?new?Class>[]?{});
?}
?
private??Collection ?getSpringFactoriesInstances(Class ?type,?Class>[]?parameterTypes,?Object...?args)?{
????????//?獲取類加載器
??ClassLoader?classLoader?=?getClassLoader();
??//?Use?names?and?ensure?unique?to?protect?against?duplicates
????????//?獲取工程名稱
??Set?names?=?new?LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type,?classLoader));
????????//?創(chuàng)建bena工廠實(shí)例
??List?instances?=?createSpringFactoriesInstances(type,?parameterTypes,?classLoader,?args,?names);
????????//?排序
??AnnotationAwareOrderComparator.sort(instances);
??return?instances;
?}
public?static?List?loadFactoryNames(Class>?factoryType,?@Nullable?ClassLoader?classLoader)?{
??String?factoryTypeName?=?factoryType.getName();
??return?loadSpringFactories(classLoader).getOrDefault(factoryTypeName,?Collections.emptyList());
?}
?
?private?static?Map>?loadSpringFactories(@Nullable?ClassLoader?classLoader)?{
??MultiValueMap?result?=?cache.get(classLoader);
??if?(result?!=?null)?{
???return?result;
??}
?
??try?{
????????//?FACTORIES_RESOURCE_LOCATION?=?"META-INF/spring.factories";
????????//?獲取加載路徑
???Enumeration?urls?=?(classLoader?!=?null??
?????classLoader.getResources(FACTORIES_RESOURCE_LOCATION)?:
?????ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
???result?=?new?LinkedMultiValueMap<>();
???while?(urls.hasMoreElements())?{
????URL?url?=?urls.nextElement();
????UrlResource?resource?=?new?UrlResource(url);
????Properties?properties?=?PropertiesLoaderUtils.loadProperties(resource);
????for?(Map.Entry,??>?entry?:?properties.entrySet())?{
?????String?factoryTypeName?=?((String)?entry.getKey()).trim();
?????for?(String?factoryImplementationName?:?StringUtils.commaDelimitedListToStringArray((String)?entry.getValue()))?{
??????result.add(factoryTypeName,?factoryImplementationName.trim());
?????}
????}
???}
???cache.put(classLoader,?result);
???return?result;
??}
??catch?(IOException?ex)?{
???throw?new?IllegalArgumentException("Unable?to?load?factories?from?location?["?+
?????FACTORIES_RESOURCE_LOCATION?+?"]",?ex);
??}
?}
private?Class>?deduceMainApplicationClass()?{
??try?{
???StackTraceElement[]?stackTrace?=?new?RuntimeException().getStackTrace();
???for?(StackTraceElement?stackTraceElement?:?stackTrace)?{
????if?("main".equals(stackTraceElement.getMethodName()))?{
?????return?Class.forName(stackTraceElement.getClassName());
????}
???}
??}
??catch?(ClassNotFoundException?ex)?{
???//?Swallow?and?continue
??}
??return?null;
?}
public?ConfigurableApplicationContext?run(String...?args)?{
????????//?計(jì)時器,相當(dāng)于System.currentTimeMillis()獲取時間進(jìn)行相減來獲取方法的耗時時間
??StopWatch?stopWatch?=?new?StopWatch();
??stopWatch.start();
??ConfigurableApplicationContext?context?=?null;
??Collection?exceptionReporters?=?new?ArrayList<>();
????????//?設(shè)置環(huán)境及沒有鼠標(biāo),鍵盤這樣的硬件信息
??configureHeadlessProperty();
????????//?獲取監(jiān)聽器
??SpringApplicationRunListeners?listeners?=?getRunListeners(args);
????????//?監(jiān)聽器開啟,進(jìn)行廣播時間
??listeners.starting();
??try?{
????????????//?獲取默認(rèn)的應(yīng)用參數(shù)
???ApplicationArguments?applicationArguments?=?new?DefaultApplicationArguments(args);
????????????//?加載系統(tǒng)配置及用戶自定義配置
???ConfigurableEnvironment?environment?=?prepareEnvironment(listeners,?applicationArguments);
????????????//?設(shè)置忽略的bean信息
???configureIgnoreBeanInfo(environment);
????????????//?打印banner,
???Banner?printedBanner?=?printBanner(environment);
????????????//?創(chuàng)建IOC容器
???context?=?createApplicationContext();
????????????//?加載異常的類型信息,和構(gòu)造方法中的是相同的套路
???exceptionReporters?=?getSpringFactoriesInstances(SpringBootExceptionReporter.class,
?????new?Class[]?{?ConfigurableApplicationContext.class?},?context);
????????????//?IOC容器前置處理
???prepareContext(context,?environment,?listeners,?applicationArguments,?printedBanner);
????????????//?刷新容器
???refreshContext(context);
????????????//?IOC容器后置處理
???afterRefresh(context,?applicationArguments);
???stopWatch.stop();
???if?(this.logStartupInfo)?{
????new?StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(),?stopWatch);
???}
???listeners.started(context);
???callRunners(context,?applicationArguments);
??}
??catch?(Throwable?ex)?{
???handleRunFailure(context,?ex,?exceptionReporters,?listeners);
???throw?new?IllegalStateException(ex);
??}
?
??try?{
???listeners.running(context);
??}
??catch?(Throwable?ex)?{
???handleRunFailure(context,?ex,?exceptionReporters,?null);
???throw?new?IllegalStateException(ex);
??}
??return?context;
?}
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/dangyongkang/article/details/111031858
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
???

?長按上方微信二維碼?2 秒
感謝點(diǎn)贊支持下哈?
評論
圖片
表情



