SpringBoot启动流程
第一步:获取并启动监听器
第二步:构造应用上下文环境
第三步:初始化应用上下文
第四步:刷新应用上下文前的准备阶段
第五步:刷新应用上下文(IOC容器的初始化过程)
invokeBeanFactoryPostProcessors(beanFactory);
IoC容器的初始化过程包括三个步骤,在invokeBeanFactoryPostProcessors()方法中完成了IoC容
器初始化过程的三个步骤。
1,第一步:Resource定位
在SpringBoot中,我们都知道他的包扫描是从主类所在的包开始扫描的,prepareContext()
方法中,会先将主类解析成BeanDefinition,然后在refresh()方法的
invokeBeanFactoryPostProcessors()方法中解析主类的BeanDefinition获取basePackage的路
径。这样就完成了定位的过程。其次SpringBoot的各种starter是通过SPI扩展机制实现的自动装
配,SpringBoot的自动装配同样也是在invokeBeanFactoryPostProcessors()方法中实现的。还有
一种情况,在SpringBoot中有很多的@EnableXXX注解,细心点进去看的应该就知道其底层是
@Import注解,在invokeBeanFactoryPostProcessors()方法中也实现了对该注解指定的配置类的
定位加载。
常规的在SpringBoot中有三种实现定位,第一个是主类所在包的,第二个是SPI扩展机制实现
的自动装配(比如各种starter),第三种就是@Import注解指定的类。(对于非常规的不说了)
2,第二步:BeanDefinition的载入
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new
LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new
ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 将当前环境变量(environment) 注册为单例bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME,
getEnvironment());
}
// 将当前系统配置(systemProperties) 注册为单例Bean
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME,
getEnvironment().getSystemProperties());
}
// 将当前系统环境 (systemEnvironment) 注册为单例Bean
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME,
getEnvironment().getSystemEnvironment());
}
}
在第一步中说了三种Resource的定位情况,定位后紧接着就是BeanDefinition的分别载入。
所谓的载入就是通过上面的定位得到的basePackage,SpringBoot会将该路径拼接成:
classpath:com/lagou/**/.class这样的形式,然后一个叫做
xPathMatchingResourcePatternResolver的类会将该路径下所有的.class文件都加载进来,然后
遍历判断是不是有@Component注解,如果有的话,就是我们要装载的BeanDefinition。大致过
程就是这样的了。
3、第三个过程:注册BeanDefinition
这个过程通过调用上文提到的BeanDefinitionRegister接口的实现来完成。这个注册过程把载入
过程中解析得到的BeanDefinition向IoC容器进行注册。通过上文的分析,我们可以看到,在IoC容
器中将BeanDefinition注入到一个ConcurrentHashMap中,IoC容器就是通过这个HashMap来持
有这些BeanDefinition数据的。比如DefaultListableBeanFactory 中的beanDefinitionMap属性。
第六步:刷新应用上下文后的扩展接口
文章内容输出来源:拉勾教育Java高薪训练营