如果看完之后感觉内容较多可以参考总结版:https://blog.csdn.net/u010597819/article/details/87456084
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" };
/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
# Application Listeners
org.springframework.context.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.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer
# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
- registerAnnotationConfigProcessors注册处理对象
- 获取上下文中的beanFactory即DefaultListableBeanFactory
- beanFactory工厂设置依赖比较器,默认为AnnotationAwareOrderComparator
- beanFactory工厂设置Autowired候选解析器,默认为ContextAnnotationAutowireCandidateResolver
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalConfigurationAnnotationProcessor:ConfigurationClassPostProcessor
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalAutowiredAnnotationProcessor:AutowiredAnnotationBeanPostProcessor
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalRequiredAnnotationProcessor:RequiredAnnotationBeanPostProcessor
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalCommonAnnotationProcessor:CommonAnnotationBeanPostProcessor
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalPersistenceAnnotationProcessor:PersistenceAnnotationBeanPostProcessor
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalEventListenerProcessor:EventListenerMethodProcessor
- registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalEventListenerFactory:DefaultEventListenerFactory
- registerDefaultFilters注册默认过滤器:AnnotationTypeFilter(Component、ManagedBean、Named)
- 设置环境及ResourceLoader即应用上下文
- postProcessApplicationContext,启动时什么都不处理,因为resourceLoader,beanNameGenerator均为null
- applyInitializers应用初始化即ApplicationContextInitializer的工厂实现:ConfigurationWarningsApplicationContextInitializer、ContextIdApplicationContextInitializer、DelegatingApplicationContextInitializer、ServerPortInfoApplicationContextInitializer等初始化对象
- ConfigurationWarningsApplicationContextInitializer addBeanFactoryPostProcessor ,为应用上下文ApplicationContext添加ConfigurationWarningsPostProcessor后置处理
- ContextIdApplicationContextInitializer 为上下文设置id
- DelegatingApplicationContextInitializer 获取env环境中的context.initializer.classes配置的初始化类列表并初始化
- ServerPortInfoApplicationContextInitializer 上下文中添加EmbeddedServletContainerInitializedEvent事件类型的监听
- listeners.contextPrepared(context)广播上下文准备完成消息
- springApplicationArguments单例模式注册至工厂
- springBootBanner不为空的情况下同样单例模式注册至工厂
- load加载上下文:createBeanDefinitionLoader创建bean定义加载器,如果isGroovyPresent则加载,如果source是component则加载,默认没有什么都不做
- listeners.contextLoaded(context)监听广播上下文加载完成消息
- 调用AbstractApplicationContext刷新上下文:spring XML 刷新上下文
- 调用钩子方法registerShutdownHook
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
...
}
- PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors,调用委派对象的后置处理,入参为应用上下文的beanFactoryPostProcessors后置处理
- 如果入参后置处理对象为BeanDefinitionRegistryPostProcessor类型,回调 postProcessBeanDefinitionRegistry 后置处理,并添加至registryPostProcessors,否则放入regular集合中regularPostProcessors常规后置处理:Invoke BeanDefinitionRegistryPostProcessors first, if any.
- 从工厂中获取BeanDefinitionRegistryPostProcessor类型bean名称,并且判断是否存在优先级(PriorityOrdered),存在则排序后放入registryPostProcessors中,调用 postProcessBeanDefinitionRegistry 后置处理:First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
- 例如:ConfigurationClassPostProcessor处理逻辑
- ConfigurationClassPostProcessor回调postProcessBeanDefinitionRegistry
- processConfigBeanDefinitions,遍历当前工厂bean,如果存在Configuration注解或者Component、ComponentScan、Import、ImportResource注解,并且没有被解析处理过,如果开启了debug日志,则打印日志,否则继续
- 校验是否存在AnnotationMetadata并且Configuration注解对象,存在则添加至configCandidates候选配置集合中
- Return immediately if no @Configuration classes were found
- 如果localBeanNameGeneratorSet缓存中不存在该类名称生成器,则为componentScanBeanNameGenerator,importBeanNameGenerator设置为internalConfigurationBeanNameGenerator
- parser.parse解析每一个配置的bean(不仅仅是Configuration注解的bean):Parse each @Configuration class
- asSourceClass封装为SourceClass实例:Application入口为StandardAnnotationMetadata类型元数据(通过自省对象获取注解的类),其余为AnnotationMetadataReadingVisitor类型元数据,根据class类调用asSourceClass解析Configuration类:Recursively process the configuration class and its superclass hierarchy.
- doProcessConfigurationClass执行处理解析配置类:processMemberClasses解析处理所有内部类、接口对象;Process any @PropertySource annotations处理PropertySource注解对象;Process any @ComponentScan annotations处理所有扫描路径下的Component注解对象(第一次为Application对象,如果basePackages为空集合则设置为当前对象所属包路径);Process any @Import annotations处理所有import注解对象(importSelector返回选择要导入的对象集合遍历导入);Process any @ImportResource annotations;Process individual @Bean methods处理sourceClass的bean注解以及sourceClass方法中存在bean注解的bean定义;Process default methods on interfaces递归遍历处理(处理逻辑同上一步Process individual @Bean methods)Application所有父接口类定义与方法如果存在bean注解添加至Application的BeanMethod(方法注入的bean)元数据中(StandardAnnotationMetadata注解,并且包含Bean注解的方法);Process superclass, if any如果Application对象有父类则处理
- 配置类缓存在ConfigurationClassParser.configurationClasses等待加载bean定义
//processImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection importCandidates, boolean checkForCircularImports) throws IOException {
...
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
//返回import要导入的class名称列表,递归处理解析导入
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
//将注解指定的ImportBeanDefinitionRegistrar绑定至configuration注解类封装的ConfigurationClass对象的importBeanDefinitionRegistrars属性中
//在处理完当前configuration注解类的解析导入后,reader再读取ConfigurationClass的importBeanDefinitionRegistrars属性中的ImportBeanDefinitionRegistrar类列表
//从ImportBeanDefinitionRegistrar中调用registerBeanDefinitions注入bean定义
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
...
}
- reader.loadBeanDefinitions:ConfigurationClassBeanDefinitionReader加载bean定义loadBeanDefinitions loadBeanDefinitionsForBeanMethod,loadBeanDefinitionsFromImportedResources,MapperScannerRegistrar加载mapper,ImportBeanDefinitionRegistrar加载Import
private void loadBeanDefinitionsFromRegistrars(Map registrars) {
for (Map.Entry entry : registrars.entrySet()) {
entry.getKey().registerBeanDefinitions(entry.getValue(), this.registry);
}
}
- postProcessBeanDefinitionRegistry处理完毕
- ConfigurationClassPostProcessor得postProcessBeanFactory处理类似,但多出下面两个步骤
- 注册ImportRegistry作为一个Bean至工厂来支持ImportAware通知动作,Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
- postProcessBeanFactory,显然不支持BeanDefinitionRegistryPostProcessor钩子方法,此时只需惰性地调用processConfigurationClasses,增强配置类enhanceConfigurationClasses,注册ImportAwareBeanPostProcessor至工厂后置处理
- 再次从工厂中获取BeanDefinitionRegistryPostProcessor类型bean名称,并且判断是否存在顺序(Ordered),存在则排序调用(排除之前回调过的) postProcessBeanDefinitionRegistry 后置处理:Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
- 调用剩余BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry回调函数:Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
- registryPostProcessors,regularPostProcessors,回调集合中的beanFactoryPostProcessor
- 从工厂中获取 BeanFactoryPostProcessor bean名称(排除之前回调过的),回调beanFactoryPostProcessor,同样的顺序,先调用PriorityOrdered类型的,其次Ordered类型的,最后普通的