中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

九江建設(shè)監(jiān)督網(wǎng)站國(guó)外友鏈買賣平臺(tái)

九江建設(shè)監(jiān)督網(wǎng)站,國(guó)外友鏈買賣平臺(tái),php和java做網(wǎng)站哪個(gè)好,網(wǎng)站要怎么做的參考文章:SpringBoot啟動(dòng)流程系列講解 參考視頻:SpringBoot啟動(dòng)流程 吐血推薦視頻:史上最完整的Spring啟動(dòng)流程 超級(jí)好文:SpringBoot執(zhí)行原理 參考文章:SpringBoot資源接口ResourceLoader和Resource學(xué)習(xí) 參考文章&…

參考文章:SpringBoot啟動(dòng)流程系列講解
參考視頻:SpringBoot啟動(dòng)流程
吐血推薦視頻:史上最完整的Spring啟動(dòng)流程
超級(jí)好文:SpringBoot執(zhí)行原理
參考文章:SpringBoot資源接口ResourceLoader和Resource學(xué)習(xí)
參考文章:到底什么是上下文(Context)
參考文章:超級(jí)好文
參考文章:這個(gè)系列的文章,讓我自愧不如,痛刪了原來2W字的內(nèi)容

文章目錄

  • Spring Boot啟動(dòng)流程
    • 服務(wù)構(gòu)建
    • 環(huán)境準(zhǔn)備
    • 容器創(chuàng)建
    • 填充容器
  • 非常重要的函數(shù)
    • getSpringFactoriesInstances()
    • getClassLoader()
    • deduceMainApplicationClass()
    • getRunListeners(String[] args)
    • SpringApplicationRunListeners.starting()
    • prepareEnvironment(SpringApplicationRunListeners, applicationArguments)
    • prepareContext()
    • refreshContext()
    • refreshContext().refresh().obtainFreshBeanFactory()
    • refreshContext().refresh().finishBeanFactoryInitialization(beanFactory)
  • 非常重要的類
    • ResourceLoader
  • 總結(jié)
    • **4. 填充容器(就是容器創(chuàng)建的refreshContext)**

Spring Boot啟動(dòng)流程

服務(wù)構(gòu)建

//SpringApplication類
//只列出幾個(gè)重要的字段和方法
public class SpringApplication {//SpringApplication默認(rèn)web容器類public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";//banner名稱,默認(rèn)為banner.txtpublic static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION;//banner位置key,默認(rèn)為spring.banner.locationpublic static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY;//調(diào)用main函數(shù)的類,也就是YanggxApplication.classprivate Class<?> mainApplicationClass;//bean名稱生成器,執(zhí)行結(jié)果為nullprivate BeanNameGenerator beanNameGenerator;//spring的環(huán)境,我們使用的是ServletWeb環(huán)境private ConfigurableEnvironment environment;//web類型,執(zhí)行結(jié)果為SERVLETprivate WebApplicationType webApplicationType;//Application初始化器,springboot啟動(dòng)過程中執(zhí)行其initialize方法private List<ApplicationContextInitializer<?>> initializers;//Application監(jiān)聽器,springboot啟動(dòng)過程執(zhí)行其onApplicationEvent方法private List<ApplicationListener<?>> listeners;/*** SpringApplication構(gòu)造函數(shù)* @param resourceLoader 資源加載器的策略接口,傳參null,* @param primarySources 傳參YanggxApplication.class*/public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {//執(zhí)行結(jié)果:nullthis.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");//Set去重:"primarySources":[com.yanggx.spring.YanggxApplication.class]this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 判斷當(dāng)前模塊web類型:"webApplicationType":"SERVLET"this.webApplicationType = WebApplicationType.deduceFromClasspath();// 加載Application初始化器// 獲取所有"META-INF/spring.factories"文件中維護(hù)的ApplicationContextInitializer子類列表// org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer// org.springframework.boot.context.ContextIdApplicationContextInitializer  // org.springframework.boot.context.config.DelegatingApplicationContextInitializer  // org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer   // org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListenersetInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 3.3 加載Application監(jiān)聽器// 獲取所有"META-INF/spring.factories"文件中維護(hù)的ApplicationListener子類列表// org.springframework.boot.ClearCachesApplicationListener// org.springframework.boot.builder.ParentContextCloserApplicationListener// org.springframework.boot.context.FileEncodingApplicationListener// org.springframework.boot.context.config.AnsiOutputApplicationListener// org.springframework.boot.context.config.ConfigFileApplicationListener// org.springframework.boot.context.config.DelegatingApplicationListener// org.springframework.boot.context.logging.ClasspathLoggingApplicationListener// org.springframework.boot.context.logging.LoggingApplicationListener// org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener// org.springframework.boot.autoconfigure.BackgroundPreinitializer// 加載的這些類都是ApplicationListener的子類setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 3.4 找到啟動(dòng)類// 拋出一個(gè)RuntimeException,然后通過堆棧信息找到啟動(dòng)類//"mainApplicationClass": com.yanggx.spring.YanggxApplication.classthis.mainApplicationClass = deduceMainApplicationClass();}
}

環(huán)境準(zhǔn)備

public class SpringApplication {public ConfigurableApplicationContext run(String... args) {//實(shí)例化一個(gè)StopWatch實(shí)例, 監(jiān)控項(xiàng)目運(yùn)行時(shí)間StopWatch stopWatch = new StopWatch();stopWatch.start();//初始化Spring上下文ConfigurableApplicationContext context = null;//初始化錯(cuò)誤報(bào)告參數(shù)Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();//配置headless,在沒有顯示器,鼠標(biāo),鍵盤的情況下,仍然可以調(diào)用顯示,輸入輸出的方法configureHeadlessProperty();//1. 發(fā)布Spring啟動(dòng)事件SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {/*2. 這一步的主要作用是處理啟動(dòng)類main函數(shù)的參數(shù), 將其封裝為一個(gè)		  DefaultApplicationArguments對(duì)象, 為prepareEnvironment()提供參數(shù)*/ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);//3.這一步的主要作用按順序加載命令行參數(shù), 系統(tǒng)參數(shù)和外部配置文件, 創(chuàng)建并配置Web環(huán)境ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);			configureIgnoreBeanInfo(environment);//4. 打印Banner圖Banner printedBanner = printBanner(environment);//....}

容器創(chuàng)建

public ConfigurableApplicationContext run(String... args) {//步驟1: 根據(jù)switch創(chuàng)建context,分別有:SERVLET、REACTIVE、NONE,并且注冊(cè)了Bean后置處理器context = createApplicationContext();//步驟2: BeanFactory是在這里創(chuàng)建的context.setApplicationStartup(this.applicationStartup);//步驟2: prepareContext()準(zhǔn)備應(yīng)用上下文prepareContext(context, environment, listeners, applicationArguments, printedBanner);//步驟3: refreshContext()刷新應(yīng)用上下文,BeanDefinition和BeanFactory都是在這里創(chuàng)建的refreshContext(context);//步驟4: 刷新完成,該方法是拓展接口,用戶可以自定義操作邏輯afterRefresh(context, applicationArguments);//步驟6: 發(fā)布Application開始事件listeners.started(context);//步驟7: 執(zhí)行Runners,用于調(diào)用項(xiàng)目中自定義的執(zhí)行器xxxRunner類,//在項(xiàng)目啟動(dòng)完成后立即執(zhí)行,這些操作只在服務(wù)啟動(dòng)時(shí)執(zhí)行一次callRunners(context, applicationArguments);//步驟8: 發(fā)布Application準(zhǔn)備事件listeners.running(context);return context;
}

填充容器

/*** 抽象父類ApplicationContext*/
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//刷新前操作,例如:清空緩存、初始化占位符prepareRefresh();//獲取并刷新beanFactory,創(chuàng)建BeanFactory和BeanDefinitionConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//設(shè)置beanFactory,配置各種beanFactory.xxx屬性prepareBeanFactory(beanFactory);//beanFactory的后置處理器:注冊(cè)與Servlet相關(guān)的特殊Bean,注冊(cè)beanDefinitionpostProcessBeanFactory(beanFactory);/*BeanFactoryPostProcessor是一個(gè)接口, 處理beanFactory中所有的bean, 在所有的beanDefinition加載完成之后, BeanFactoryPostProcessor可以對(duì)beanDefinition進(jìn)行屬性的修改, 之后再進(jìn)行bean實(shí)例化*/invokeBeanFactoryPostProcessors(beanFactory);//beanFactory注冊(cè)后置處理器,對(duì)bean實(shí)例的增強(qiáng)registerBeanPostProcessors(beanFactory);//初始化messageSourceinitMessageSource();//初始化Application事件發(fā)布器initApplicationEventMulticaster();//初始化其他特殊的bean,例如實(shí)例化了TomcatWebServeronRefresh();//注冊(cè)監(jiān)聽器registerListeners();//完成beanFactory初始化finishBeanFactoryInitialization(beanFactory);//完成刷新,發(fā)布完成事件,實(shí)例化了所有beanfinishRefresh();        }
}

非常重要的函數(shù)

getSpringFactoriesInstances()

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {ClassLoader classLoader = this.getClassLoader();Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;}
	public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {//主要獲取spring.factories中的key,key對(duì)應(yīng)接口全名String factoryTypeName = factoryType.getName();//篩選Map中key為factoryTypeName對(duì)應(yīng)放到list返回	return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());}
	//會(huì)把Spring.factories文件中所有鍵值對(duì)放到Map中,其實(shí)就是緩存//classLoader參數(shù)就是"META-INF/spring.factories"加載器private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {//如果緩存已經(jīng)有Spring.factories,那就從緩存中拿MultiValueMap<String, String> result = cache.get(classLoader);if (result != null) {return result;}//如果緩存中沒有Spring.factories,那就從重新加載到緩存Enumeration<URL> urls = (classLoader != null ?// FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories" 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;}
	private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,ClassLoader classLoader, Object[] args, Set<String> names) {List<T> instances = new ArrayList<>(names.size());for (String name : names) {try {//通過反射機(jī)制創(chuàng)建實(shí)例Class<?> instanceClass = ClassUtils.forName(name, classLoader);Assert.isAssignable(type, instanceClass);Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);T instance = (T) BeanUtils.instantiateClass(constructor, args);instances.add(instance);}catch (Throwable ex) {throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);}}return instances;}

總結(jié):

  1. loadSpringFactories(@Nullable ClassLoader classLoader):判斷緩存是否有Spring.factories文件,如果有就提取整個(gè)spring.factories。如果沒有就加載到緩存再提取。
  2. loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader):從spring.factories文件中獲取指定factoryType
  3. createSpringFactoriesInstances(Class type, Class<?>[] parameterTypes,
    ClassLoader classLoader, Object[] args, Set names):將loadFactoryNames()返回的factoryType,通過反射機(jī)制實(shí)例化
  4. getSpringFactoriesInstances(Class type, Class<?>[] parameterTypes, Object… args):獲取createSpringFactoriesInstances()返回的實(shí)例instances,返回實(shí)例

getClassLoader()

  1. 我們都知道java程序?qū)懞靡院笫且?java(文本文件)的文件存在磁盤上,然后,我們通過(bin/javac.exe)編譯命令把.java文件編譯成.class文件(字節(jié)碼文件),并存在磁盤上。
    但是程序要運(yùn)行,首先一定要把.class文件加載到JVM內(nèi)存中才能使用的,我們所講的classLoader,就是負(fù)責(zé)把磁盤上的.class文件加載到JVM內(nèi)存中
  2. 你可以認(rèn)為每一個(gè)Class對(duì)象擁有磁盤上的那個(gè).class字節(jié)碼內(nèi)容,每一個(gè)class對(duì)象都有一個(gè)getClassLoader()方法,得到是誰把我從.class文件加載到內(nèi)存中變成Class對(duì)象的

deduceMainApplicationClass()

private Class<?> deduceMainApplicationClass() {try {//通過一個(gè)RuntimeException,獲取器堆棧信息StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();for (StackTraceElement stackTraceElement : stackTrace) {if ("main".equals(stackTraceElement.getMethodName())) {//堆棧中包含main方法,實(shí)例化一個(gè)該類的對(duì)象return Class.forName(stackTraceElement.getClassName());}}}catch (ClassNotFoundException ex) { }return null;
}

getRunListeners(String[] args)

	//當(dāng)前只能獲取SpringApplicationRunListener子類列表EventPublishingRunListenerprivate SpringApplicationRunListeners getRunListeners(String[] args) {Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));}

SpringApplicationRunListeners.starting()

//該SpringApplicationRunListeners存在多個(gè)子類,在下面starting方法中,會(huì)調(diào)用對(duì)應(yīng)子類的starting方法
class SpringApplicationRunListeners {//發(fā)布啟動(dòng)事件public void starting() {for (SpringApplicationRunListener listener : this.listeners) {//目前調(diào)用EventPublishingRunListener的starting方法listener.starting();}}//其他事件都是相同的代碼
}
//不僅僅是ApplicationListeners存在很多子類,EventPublishingRunListener也有很多子類
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {//SpringApplication對(duì)象private final SpringApplication application;//命令函參數(shù)private final String[] args;//事件廣播器private final SimpleApplicationEventMulticaster initialMulticaster;public EventPublishingRunListener(SpringApplication application, String[] args) {this.application = application;this.args = args;this.initialMulticaster = new SimpleApplicationEventMulticaster();// 通過application.getListeners(),獲取到Listener列表// ConfigFileApplicationListener// AnsiOutputApplicationListener// LoggingApplicationListener// ClasspathLoggingApplicationListener// BackgroundPreinitializer// DelegatingApplicationListener// ParentContextCloserApplicationListener// ClearCachesApplicationListener// FileEncodingApplicationListener// LiquibaseServiceLocatorApplicationListenerfor (ApplicationListener<?> listener : application.getListeners()) {//將listener添加到事件廣播器initialMulticasterthis.initialMulticaster.addApplicationListener(listener);}}@Overridepublic void starting() {// 廣播器廣播ApplicationStartingEvent事件this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));}//其他事件發(fā)布都是相同的代碼//...
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));//調(diào)用父類getApplicationListeners方法//遍歷所有支持ApplicationStartingEvent事件的監(jiān)聽器//LoggingApplicationListener//BackgroundPreinitializer//DelegatingApplicationListener//LiquibaseServiceLocatorApplicationListenerfor (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {//此時(shí)的executor為nullExecutor executor = getTaskExecutor();if (executor != null) {executor.execute(() -> invokeListener(listener, event));}else {//調(diào)用listenerinvokeListener(listener, event);}}}	
}
    protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {ErrorHandler errorHandler = this.getErrorHandler();if (errorHandler != null) {try {this.doInvokeListener(listener, event);} catch (Throwable var5) {errorHandler.handleError(var5);}} else {this.doInvokeListener(listener, event);}}
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {//調(diào)用listener的onApplicationEvent方法listener.onApplicationEvent(event);}
onApplicationEvent(event){到這里就不再深究了,這個(gè)方法有三十個(gè)實(shí)現(xiàn)類,操作基本上就是綁定環(huán)境,設(shè)置參數(shù)等等
}

總結(jié):

  1. SpringApplicationRunListeners.starting()調(diào)用了EventPublishingRunListener.starting();
  2. EventPublishingRunListener.starting()調(diào)用了廣播器initialMulticaster.multicastEvent()發(fā)布SpringApplication啟動(dòng)事件
  3. initialMulticaster.multicastEvent()分別調(diào)用了LoggingApplicationListener、BackgroundPreinitializer、DelegatingApplicationListener、LiquibaseServiceLocatorApplicationListener的invokeListener()方法
    invokeListener()——doInvokeListener()——onApplicationEvent()——設(shè)置參數(shù)、綁定環(huán)境等等

prepareEnvironment(SpringApplicationRunListeners, applicationArguments)

    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {//獲取或者創(chuàng)建環(huán)境,根據(jù)switch判斷,選擇SERVLET、REACTIVE、NONE類型ConfigurableEnvironment environment = getOrCreateEnvironment();//配置環(huán)境:為environment配置“共享的類型轉(zhuǎn)換服務(wù)”,即:A數(shù)據(jù)類型變成B數(shù)據(jù)類型 //然后將defaultProperties和args分別添加到environment的propertySources中configureEnvironment(environment, applicationArguments.getSourceArgs());//發(fā)布環(huán)境準(zhǔn)備事件listeners.environmentPrepared(environment);//如果指定了main函數(shù),那么會(huì)將當(dāng)前環(huán)境綁定到指定的SpringApplication中bindToSpringApplication(environment);if (!this.isCustomEnvironment) {//環(huán)境轉(zhuǎn)換:如果environment.class和模塊EnvironmentClass()不一致,就轉(zhuǎn)換成一樣的environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());}//將環(huán)境依附到PropertySourcesConfigurationPropertySources.attach(environment);return environment;}

prepareContext()

	private void prepareContext(ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {//設(shè)置context環(huán)境:統(tǒng)一ApplicationContext與Application.environment一致context.setEnvironment(environment);//設(shè)置ApplicationContext.beanNameGenerator、resourceLoader、classLoader、類型轉(zhuǎn)換服務(wù)postProcessApplicationContext(context);//獲取6個(gè)初始化器并執(zhí)行初始化方法,例如設(shè)置元數(shù)據(jù)、配置警告、獲取應(yīng)用名稱applyInitializers(context);//發(fā)布contextPrepared事件listeners.contextPrepared(context);if (this.logStartupInfo) {//配置了info日志//打印啟動(dòng)和profile日志logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}//獲取到DefaultListableBeanFactory實(shí)例ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();//注冊(cè)名為springApplicationArguments,值為applicationArguments的單例beanbeanFactory.registerSingleton("springApplicationArguments", applicationArguments);//banner不為空,那么注冊(cè)名為springBootBanner,值為printedBanner的單例beanif (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}if (beanFactory instanceof DefaultListableBeanFactory) {//allowBeanDefinitionOverriding默認(rèn)為false((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}// 獲取sources列表,獲取到我們的YanggxApplication.classSet<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");//初始化bean加載器,并加載bean到應(yīng)用上下文load(context, sources.toArray(new Object[0]));//發(fā)布contextLoaded事件listeners.contextLoaded(context);}

refreshContext()

    //刷新應(yīng)用上下文,注冊(cè)關(guān)閉應(yīng)用鉤子private void refreshContext(ConfigurableApplicationContext context) {refresh(context);if (this.registerShutdownHook) context.registerShutdownHook();}
/*** 抽象父類ApplicationContext*/
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//清空緩存、清空監(jiān)聽器、判斷必要屬性是否被忽略、打印日志、初始化占位符、設(shè)置earlyApplicationEventsprepareRefresh();//獲取并刷新beanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();/*配置classLoader為當(dāng)前context的classLoader設(shè)置BeanExpressionResolver, 解析EL表達(dá)式設(shè)置屬性編輯器添加BeanPostProcessor配置自動(dòng)裝配手工注冊(cè)environment相關(guān)bean*/prepareBeanFactory(beanFactory);/*注冊(cè)basepackages注冊(cè)annotatedClasses注冊(cè)了request和session兩個(gè)scopes注冊(cè)幾個(gè)Autowired依賴類	*/postProcessBeanFactory(beanFactory);/*BeanFactoryPostProcessor接口用于增強(qiáng)BeanFactory,Spring IoC 容器允許 BeanFactoryPostProcessor 在容器實(shí)例化任何 bean 之前讀取bean 的定義,并可以修改它。例如:public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, 		List<BeanFactoryPostProcessor> beanFactoryPostProcessors) */invokeBeanFactoryPostProcessors(beanFactory);//beanFactory注冊(cè)后置處理器,對(duì)bean實(shí)例的增強(qiáng)registerBeanPostProcessors(beanFactory);//初始化messageSourceinitMessageSource();//初始化Application事件發(fā)布器initApplicationEventMulticaster();//初始化其他特殊的bean,例如實(shí)例化了TomcatWebServeronRefresh();//注冊(cè)監(jiān)聽器registerListeners();//完成beanFactory初始化finishBeanFactoryInitialization(beanFactory);//完成刷新,發(fā)布完成事件,實(shí)例化了所有beanfinishRefresh();}        }
}
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {protected void prepareRefresh() {//記錄開始時(shí)間,調(diào)整active狀態(tài)this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);//初始化占位符,例如:$,#,{}initPropertySources();//如果屬性中缺少requiredProperties,那么拋出MissingRequiredPropertiesExceptiongetEnvironment().validateRequiredProperties();//清空監(jiān)聽器if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}//初始化earlyApplicationEventsthis.earlyApplicationEvents = new LinkedHashSet<>();}
}

refreshContext().refresh().obtainFreshBeanFactory()

/*refreshBeanFactory():創(chuàng)建beanFactory、指定序列化Id、定制beanFactory、加載bean定義getBeanFactory():返回beanFactory實(shí)例
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {//1.初始化beanFactory,并執(zhí)行加載和解析配置操作refreshBeanFactory();//返回beanFactory實(shí)例ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {... @Overrideprotected final void refreshBeanFactory() throws BeansException {//判斷是否存在beanFactoryif (hasBeanFactory()) {// 注銷所有的單例destroyBeans();//重置beanFactorycloseBeanFactory();}try {//創(chuàng)建beanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();//指定序列化id,如果需要的話,讓這個(gè)BeanFactory從id反序列化到BeanFactory對(duì)象beanFactory.setSerializationId(getId());//定制BeanFactorycustomizeBeanFactory(beanFactory);//下載BeanDefinitions,放到BeanDefinitionsMaploadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}...
}

refreshContext().refresh().finishBeanFactoryInitialization(beanFactory)

/* 根據(jù)loadBeanDefinitions加載的BeanDinition到BeanDefinitionMap,再從BeanDefinitionMap拿出來BeanDefinitionMap創(chuàng)建Bean
*/
createBean(){//1. createBeanInstance通過反射機(jī)制獲取Bean的構(gòu)造方法,然后創(chuàng)建Bean。當(dāng)然,如果構(gòu)造方法需要參數(shù),就會(huì)到單例池中查找。//2. populateBean填充Bean屬性//3. 初始化1. 初始化容器信息,通過invokeAwareMethods(),喚醒各種Aware接口,獲取Bean在容器中的信息2. 初始化Bean成普通對(duì)象:通過invokeInitMethods(),執(zhí)行Bean的初始化方法,這個(gè)方法可以通過實(shí)現(xiàn)InitialzingBean接口實(shí)現(xiàn)的afterPropertiesSet方法。3. AOP操作Bean成:初始化之前和之后處理各種Bean的后置處理器,即在invokeInitMethods()之前和之后分別執(zhí)行applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()//4. 注冊(cè)銷毀實(shí)現(xiàn)了銷毀接口DisposableBean,在registerDisposableBean方法注冊(cè)指定的Bean在銷毀時(shí)可以直接執(zhí)行destroy方法銷毀Bean
}addSingleton(){將上面create出來的Bean放入單例池就可以獲取和使用了
}

非常重要的類

ResourceLoader

//默認(rèn)的資源加載器
public class DefaultResourceLoader implements ResourceLoader {@Nullableprivate ClassLoader classLoader;//自定義ProtocolResolver, 用于獲取資源private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);//private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);//實(shí)例化ClassLoaderpublic DefaultResourceLoader() {this.classLoader = ClassUtils.getDefaultClassLoader();}//加載資源@Overridepublic Resource getResource(String location) {Assert.notNull(location, "Location must not be null");//自定義資源加載方式for (ProtocolResolver protocolResolver : this.protocolResolvers) {//調(diào)用ProtocolResolver的resolve方法Resource resource = protocolResolver.resolve(location, this);if (resource != null) {//如果獲取到資源,立即返回return resource;}}if (location.startsWith("/")) {//先判斷是否是根目錄return getResourceByPath(location);}else if (location.startsWith(CLASSPATH_URL_PREFIX)) {//再判斷是否是classpath下的資源return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());}else {try {//先當(dāng)做一個(gè)URL處理URL url = new URL(location);//先判斷是否是一個(gè)file//不是file的話,再從URL中獲取return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));}catch (MalformedURLException ex) {//獲取不到資源的話//當(dāng)做resource處理return getResourceByPath(location);}}}
}

總結(jié)

1. 服務(wù)構(gòu)建

  • 設(shè)置primarySources:YanggxApplication.class
  • 設(shè)置webType:SERVLET
  • 從Spring.factories獲取初始化器
  • 從Spring.factories獲取監(jiān)聽器ApplicationListener
  • 設(shè)置啟動(dòng)類:YanggxApplication.class

2. 環(huán)境準(zhǔn)備

  • 發(fā)布Spring啟動(dòng)事件listeners.starting()
  • 封裝args參數(shù) new DefaultApplicationArguments(args);
  • 配置環(huán)境并讓環(huán)境生效prepareEnvironment() & configureIgnoreBeanInfo()
  • 打印Banner圖printBanner(environment)

3. 容器創(chuàng)建

  • 創(chuàng)建容器createApplicationContext()
  • 設(shè)置容器prepareContext()
  • 刷新容器refreshContext(),這里也是填充容器,重點(diǎn)是 invokeBeanFactoryPostProcessors(beanFactory);和onRefresh()
  • 執(zhí)行Runners

4. 填充容器(就是容器創(chuàng)建的refreshContext)

http://www.risenshineclean.com/news/23281.html

相關(guān)文章:

  • 專業(yè)網(wǎng)站建設(shè)知識(shí)免費(fèi)seo快速收錄工具
  • 公司做網(wǎng)站哪里做南京seo優(yōu)化
  • 網(wǎng)站建設(shè)服務(wù)流程企業(yè)推廣方案
  • 具有價(jià)值的常州做網(wǎng)站安卓aso優(yōu)化工具
  • 紅星美凱龍建設(shè)事業(yè)中心網(wǎng)站網(wǎng)站免費(fèi)高清素材軟件
  • 用哪個(gè)程序做網(wǎng)站收錄好今日熱點(diǎn)新聞?lì)^條排行榜
  • 凡科建站官網(wǎng)登滄州網(wǎng)站運(yùn)營(yíng)公司
  • seo網(wǎng)站優(yōu)化詳解怎么優(yōu)化網(wǎng)站
  • 網(wǎng)站 建設(shè)標(biāo)準(zhǔn)web前端培訓(xùn)費(fèi)用大概多少
  • 濟(jì)南學(xué)生網(wǎng)站建設(shè)求職購物網(wǎng)站頁面設(shè)計(jì)
  • 什么網(wǎng)站可以做微官網(wǎng)市場(chǎng)調(diào)研的四個(gè)步驟
  • 北京網(wǎng)站制作公司興田德潤(rùn)實(shí)惠軟件開發(fā)培訓(xùn)
  • ps做分享類網(wǎng)站效果圖地推接單平臺(tái)app排行榜
  • 營(yíng)業(yè)執(zhí)照怎么做增項(xiàng) 在網(wǎng)站上操作網(wǎng)站搭建公司
  • 學(xué)網(wǎng)站建設(shè)多久能學(xué)會(huì)每天4元代發(fā)廣告
  • 建設(shè)網(wǎng)站程序百度seo關(guān)鍵詞排名優(yōu)化軟件
  • 集群注冊(cè)的公司可以做網(wǎng)站備案深圳互聯(lián)網(wǎng)公司排行榜
  • 莘縣網(wǎng)站建設(shè)電話一諾網(wǎng)絡(luò)推廣公司
  • 太原做網(wǎng)站公司運(yùn)營(yíng)長(zhǎng)沙網(wǎng)絡(luò)推廣小公司
  • win7 iis配置asp.net網(wǎng)站品牌營(yíng)銷策略分析
  • wordpress做圖片站網(wǎng)站建設(shè)深圳公司
  • 國(guó)外好的網(wǎng)站空間最近10條重大新聞
  • 國(guó)家官方網(wǎng)站seo關(guān)鍵詞排名優(yōu)化app
  • h5都用什么網(wǎng)站廣州百度seo 網(wǎng)站推廣
  • 怎樣自創(chuàng)網(wǎng)站寧波網(wǎng)站推廣優(yōu)化公司電話
  • 畢業(yè)設(shè)計(jì)軟件開發(fā)網(wǎng)站開發(fā)手機(jī)做網(wǎng)頁的軟件
  • 網(wǎng)站上的圖片帶店面是怎么做的怎么做市場(chǎng)推廣
  • 建立企業(yè)網(wǎng)站要多少錢足球比賽統(tǒng)計(jì)數(shù)據(jù)
  • 公司注冊(cè)網(wǎng)站官網(wǎng)電商如何推廣自己的產(chǎn)品
  • 網(wǎng)站開發(fā)的安全性原則優(yōu)化關(guān)鍵詞的作用