记录一次springboot启动流程不完整版
1.Sort ApplicationInitializer:
2.sort Listener:
3.getRunListener:
4.eventPublishingRunListener.starting 发布启动中事件;
构建 ApplicationArguments 参数,
4.1prepareEnvement:
[StubPropertySource {name='servletConfigInitParams'},
StubPropertySource {name='servletContextInitParams'},
PropertiesPropertySource {name='systemProperties'},
SystemEnvironmentPropertySource {name='systemEnvironment'}]
5.eventPublistRunlistener.environmentPrepared (环境变量) 发布环境已经准备好了的事件:
propertySources:[
ConfigurationPropertySourcesPropertySource {name='configurationProperties'},
StubPropertySource {name='servletConfigInitParams'},
StubPropertySource {name='servletContextInitParams'},
PropertiesPropertySource {name='systemProperties'},
SystemEnvironmentPropertySource {name='systemEnvironment'}]
最后返回的environment如下:
[ConfigurationPropertySourcesPropertySource {name='configurationProperties'},
MapPropertySource {name='bootstrap'},
PropertiesPropertySource {name='systemProperties'},
OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'},
MapPropertySource {name='springCloudClientHostInfo'},
OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/bootstrap.yml]'}]
6.创建ConfigurableApplicationContext ,这里只是通过构造函数创建一个基本对象
7.prepareContext 准备容器内容 ,
入参(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner)
-
context.setEnvironment(environment); 容器设置环境信息
-
postProcessApplicationContext(ConfigurableApplicationContext context)对容器增强
-
调用applyInitializers ,对initializer进行调用初始化。
-
listeners.contextPrepared(context); 最后又广播出去ApplicationContextInitializedEvent事件
-
从容器中获取 ConfigurableListableBeanFactory
-
向容器中注册springApplicationArguments
-
设置setAllowBeanDefinitionOverriding
-
添加ddBeanFactoryPostProcessor------>LazyInitializationBeanFactoryPostProcessor implements BeanFactoryPostProcessor
-
获取所有source
其中包括BootstrapImportSelectorConfiguration
这里重点是将spring.factories中的BootstrapConfiguration和环境中配置的spring.cloud.bootstrap.sources 进行合并,然后排序,然后返回。。相当于给容器中注入了bean!
image
- 执行this.load(context, sources.toArray(new Object[0]));
protected void load(ApplicationContext context, Object[] sources) {
if (logger.isDebugEnabled()) {
logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
}
BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);
if (this.beanNameGenerator != null) {
loader.setBeanNameGenerator(this.beanNameGenerator);
}
if (this.resourceLoader != null) {
loader.setResourceLoader(this.resourceLoader);
}
if (this.environment != null) {
loader.setEnvironment(this.environment);
}
loader.load();
}
private int load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class) {
return this.load((Class)source);
} else if (source instanceof Resource) {
return this.load((Resource)source);
} else if (source instanceof Package) {
return this.load((Package)source);
} else if (source instanceof CharSequence) {
return this.load((CharSequence)source);
} else {
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}
}
根据不同的类型进行load,其中包括Class的register、Package 的scan 、Resource的loadBeanDefinitions;总之重写了很多的类型。
- listeners.contextLoaded(context);告诉监听器容器已经启动完成了。
8.DefaultListableBeanFactory
本文来自博客园,作者:Eular,转载请注明原文链接:https://www.cnblogs.com/euler-blog/p/18616019
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通