private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
//设置环境
context.setEnvironment(environment);
//上下文后处理
postProcessApplicationContext(context);
//初始化器执行 就是我们最初取出来放到springApplication.initializers中
//初始化器有很多 看下面的详细分析
applyInitializers(context);
//监听器执行
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 向beanFactory注册单例 关于参数的bean
beanFactory.registerSingleton(“springApplicationArguments”, applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton(“springBootBanner”, printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 获取全部资源
Set sources = getAllSources();
Assert.notEmpty(sources, “Sources must not be empty”);
//这个操作我们看下面的详情
load(context, sources.toArray(new Object[0]));
// 向上下文中添加ApplicationListener,并广播ApplicationPreparedEvent事件
listeners.contextLoaded(context);
}
初始化器有几个:
load(context, sources.toArray(new Object[0])) 方法详情:
BeanDefinitionLoader对象里面封装了AnnotatedBeanDefinitionReader,XmlBeanDefinitionReader和ClassPathBeanDefinitionScanner 。这三个类是用来读取bean的。
Class用AnnotatedBeanDefinitionReader处理
Resource用XmlBeanDefinitionReader处理
Package用ClassPathBeanDefinitionScanner处理
通过debug跟踪到方法里面 我们发现 目前我们的source只有一个:class 就是我们的启动引导类,是class类型;先判断引导类是否有被component注解修饰,很显然是(SpringBootApplication注解中包含component注解),那么AnnotatedBeanDefinitionReader来处理:将 启动引导类 封装成一个名叫 { 启动引导类名称} 的BeanDefinition对象,并将其注册到了beanFactory的BeanDefinitionMap中。
listeners.contextLoaded(context) 方法详解:
事件传播 :
ConfigFileApplicationListener 向context注册了一个BeanFactoryPostProcessor(PropertySourceOrderingPostProcessor)实例;该实例后面会对我们的property sources进行重排序,另外该实例拥有上下文的引用。
LoggingApplicationListener向beanFactory中注册了一个名叫springBootLoggingSystem的单例bean,也就是我们的日志系统bean。
BackgroundPreinitializer 目前什么也没做
DelegatingApplicationListener 目前什么也没做
一般一个单例对象注册到beanFactory中,beanFactory会有2个属性都添加此单例对象信息:singletonObjects、registeredSingletons
Map<String, Object> singletonObjects = new ConcurrentHashMap<>(),key是bean name,value是单例对象
Set registeredSingletons = new LinkedHashSet<>(),存放的是bean name
一般一个 bean定义 注册到beanFactory中是,beanFactory也会有2个属相会添加此bean定义信息:beanDefinitionMap、beanDefinitionNames
List beanDefinitionNames = new ArrayList<>(),beanDefinition的名称列表
Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(),key是beanDefinition的名称,value是beanDefinition对象
另外beanFactory中Set manualSingletonNames = new LinkedHashSet<>,按注册顺序存放手动注册的单例的名称。
本文参考子:https://www.cnblogs.com/youzhibing/p/9697825.html