1.SpringBoot的源码CommandLineRunner和ApplicationRunner源码分析
2.Spring Bootå°è®°
SpringBoot的CommandLineRunner和ApplicationRunner源码分析
深入探究SpringBoot中的ApplicationRunner和CommandLineRunner接口。这两个接口在启动SpringBoot应用时起到关键作用,分析下面将对它们进行源码分析。源码
首先,分析让我们聚焦于ApplicationRunner接口,源码专门广告的网站源码其内部定义了一个名为run的分析英雄联盟防封源码方法,无需额外参数,源码源码如下所示,分析展示了接口的源码基本框架。
接着,分析审视CommandLineRunner接口,源码同样地,分析它也仅定义了一个run方法,源码主图板块源码公式同样没有额外参数,分析源码内容在此。源码接口设计简洁,旨在支持特定逻辑的正规卡易信源码执行。
为了更直观地理解这些接口的运行,让我们通过实际项目进行演示。具体操作是将SpringBoot项目打包为JAR文件并执行。
在项目执行过程中,冒险岛117源码观察并分析代码,可以揭示更多关于ApplicationRunner和CommandLineRunner接口如何在实际应用中运作的细节。
接下来,以ApplicationRunnerDemo和CommandLineRunnerDemo为例,深入探讨接口的使用。首先,审视ApplicationRunnerDemo类,了解如何定义实现ApplicationRunner接口的实例并注入应用上下文。然后,通过CommandLineRunnerDemo类,进一步探索实现CommandLineRunner接口的实例,关注参数传递的机制以及接口执行的时机。
至此,参数传递、参数解析以及获取参数的过程已经清晰呈现。此外,ApplicationRunner和CommandLineRunnerDemo的执行时机也已明确阐述,为理解SpringBoot启动过程中的关键逻辑提供了深入洞察。
Spring Bootå°è®°
1ãApplicationContextInitializerï¼å¨Springä¸ä¸æ被å·æ°ä¹åè¿è¡åå§åçæä½ãè¿ä¸ªæ¶åå·²ç»å建äºApplicationContext ï¼ä½æ¯æ²¡ærefresh()ï¼ApplicationContextInitializer对ApplicationContextè¿è¡åå§è¯æä½ã2ãSpringApplicationRunListenerï¼å¯¹ApplicationContextçè¿è¡å个æ¶æçäºä»¶è¿è¡å¹¿æï¼æ¶äºä»¶è½å¤è¢«ApplicationListeneræçå¬å°ã
3ãRunnerï¼Springä¸ä¸æåç½®å¤ç Runnerså¯ä»¥æ¯ä¸¤ä¸ªæ¥å£çå®ç°ç±»ï¼ org.springframework.boot.ApplicationRunner org.springframework.boot.CommandLineRunner å ¶å®æ²¡æä»ä¹ä¸åä¹å¤ï¼é¤äºæ¥å£ä¸çrunæ¹æ³æ¥åçåæ°ç±»åæ¯ä¸ä¸æ ·ç以å¤ãä¸ä¸ªæ¯å°è£ 好çApplicationArgumentsç±»åï¼å¦ä¸ä¸ªæ¯ç´æ¥çStringä¸å®é¿æ°ç»ç±»åãå æ¤æ ¹æ®éè¦éæ©ç¸åºçæ¥å£å®ç°å³å¯ã
SpringBootå¯å¨çæ¶åï¼ä¸è®ºè°ç¨ä»ä¹æ¹æ³ï¼é½ä¼æé ä¸ä¸ªSpringApplicationçå®ä¾ï¼ç¶åè°ç¨è¿ä¸ªå®ä¾çrunæ¹æ³ï¼è¿æ ·å°±è¡¨ç¤ºå¯å¨SpringBootã
å¨runæ¹æ³è°ç¨ä¹åï¼ä¹å°±æ¯æé SpringApplicationçæ¶åä¼è¿è¡åå§åçå·¥ä½ï¼åå§åçæ¶åä¼å以ä¸å 件äºï¼
SpringApplicationæé å®æä¹åè°ç¨runæ¹æ³ï¼å¯å¨SpringApplicationï¼runæ¹æ³æ§è¡çæ¶åä¼å以ä¸å 件äºï¼
å¨@SpringBootApplicationæ ç¾ä¸å¼å ¥äºEnableAutoConfigurationImportSelectorï¼å ¶ä¸è°ç¨äºselectImports()æ¹æ³ï¼æ¹æ³ä¸è°ç¨org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector#getCandidateConfigurationsæ¹æ³ï¼ä½¿ç¨SpringFactoryLoaderæMETA-INFæ件夹ä¸çspring.factoriesæ件ä¸EnableAutoConfiguration为keyçæ件å è½½äºã å è½½çæä»¶å ¨é¨é½æ¯java configé ç½®æ件ï¼æé»è®¤é ç½®ï¼ï¼å©ç¨@Conditional(Class<? extends Condition>[]) æ ç¾ï¼å¯¹ç¸åºçbeanè¿è¡éæ©æ§çå è½½ã
æ¯è¾åºæ¬èä¸éè¦çä¸ä¸ªç±»ï¼è¿è¡å è½½äºMATE-INFä¸çspring.factories æ件
@Conditionalæ ç¾æ¯å ¨é¨Conditionalç¸å ³æ ç¾çæ ¹æºã æºç ä¸Conditionalæ ç¾ä½¿ç¨çæ¯ConditionEvaluatoræ¥è§£æï¼å¦ä¸ org.springframework.context.annotation.AnnotatedBeanDefinitionReader#registerBean(java.lang.Class<?>, java.lang.String, java.lang.Class<? extends java.lang.annotation.Annotation>...) org.springframework.context.annotation.ConditionEvaluator#shouldSkip(org.springframework.core.type.AnnotatedTypeMetadata, org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase)
å¨åå§åAnnotationConfigApplicationContextçæ¶åï¼å¯¹ConfigurationClassPostProcessorãAutowiredAnnotationBeanPostProcessorçç±»è¿è¡äºæ³¨åãå¦ä¸
ConfigurationClassPostProcessoræ¯ä¸ä¸ªBeanFactoryPostProcessorï¼æ以ä¼å¯¹BeanDefinitionRegistryæè BeanDefinitionå建ä¹åè¿è¡åç½®å å·¥ï¼refreshæ¹æ³ä¸ï¼å·²ç»å建äºBeanFactoryï¼å ·ä½å°è¿è¡å°åªéçæºç ï¼ã
import解æåçæ ¹æ®çæ¯ConfigurationClassPostProcessorï¼ConfigurationClassPostProcessorçå è½½è¿ç¨åèä¸é¢ 主è¦åæ为å¥@importæ ç¾æ¯å¼å ¥é ç½®çä½æ¯å´è½å¤è°ç¨Selectorçæ¹æ³ org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>) org.springframework.context.annotation.ConfigurationClassParser#processDeferredImportSelectors æ¥çå¦ä¸ï¼è°ç¨äºselectImportsæ¹æ³