首先springboot的最经典的启动类是
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
SpringApplication的run方法
实例化了一个SpringApplication对象
调用SpringApplication的构造器
初始化对象
getSpringFactoriesInstances
获取了默认的类加载器,新建了一个set
loadFactoryNames
获取了BootstrapRegistryInitializer的类名
loadSpringFactories
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
Map<String, List<String>> result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
Map<String, List<String>> result = new HashMap();
try {
Enumeration<URL> urls = classLoader.getResources("META-INF/spring.factories");
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Map.Entry<?, ?> entry = (Map.Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
String[] var10 = factoryImplementationNames;
int var11 = factoryImplementationNames.length;
for(int var12 = 0; var12 < var11; ++var12) {
String factoryImplementationName = var10[var12];
((List)result.computeIfAbsent(factoryTypeName, (key) -> {
return new ArrayList();
})).add(factoryImplementationName.trim());
}
}
}
result.replaceAll((factoryType, implementations) -> {
return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
});
cache.put(classLoader, result);
return result;
} catch (IOException var14) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
}
}
}
先从缓存中去类加载器对应的result,取不到就开始加载META-INF/spring.factories文件,加载后放入cache(key:classLoader,value:map(spring.factories对应的keyvalue))
找有没有BootstrapRegistryInitializer对应的结果
createSpringFactoriesInstances
通过反射创建springFactories对应的bean
setInitializers
getSpringFactoriesInstances
和上面的一样,获取ApplicationContextInitializer对应的bean设置为初始化器
找到7个
setListeners
getSpringFactoriesInstances
和上面的一样,获取ApplicationListener对应的bean设置为监听器。
找到6个
deduceMainApplicationClass
借助运行时异常的调用栈来寻找main函数的位置,最后拿到启动类。
调用run方法
接下来调用prepaerContext,进行上下文环境的准备
prepareContext
设置环境,应用初始化器,初始化监听器,从上下文中获取BeanFactory并注册springApplicationArguments和springBootBanner
load
获取BeanDefinitionloader,并调用他的load方法
load
load
注册启动类
refreshContext
准备调用spring的refresh
refresh
spring的refresh有13种的方法
prepareRefresh
initPropertySources
初始化servlet
validateRequiredProperties
校验必要属性,没什么用吧,没看见跑起来
初始化earlyApplicationListeners
obtainFreshBeanFactory
getBeanFactory
获取BeanFactory
prepareBeanFactory
初始化BeanFactory配置相关属性
设置自动装配时会忽略的bean,比如EnvironmentAware等。
注册BeanFactory等bean
注册一些容器bean
postProcessBeanFactory
设置postProcessBeanFactory
添加了一个WebApplicationContextServletContextAwareProcessor
添加了对ServletContextAware的忽略
invokeBeanFactoryPostProcessors
总的来说就是实例化了实现了BeanFactoryPostProcessor接口的类并调用了他们
首先如果是BeanDefinitionRegistry,遍历beanFactoryPostProcessors,如果是BeanDefinitionRegistryPostProcessor那就注册internalCachingMetadataReaderFactory。并加入registerProcessors(和BeanDefinition有关的)否则加入regularPostProcessors。
获取实现了PriorityOrdered的类bean currentRegistryProcessors 和名字processedBeans。
对currentRegistryProcessors根据下拉根据实收实现了PriorityOrdered 在根据order值进行排序
registryProcessors添加currentRegistryProcessors的内容
执行postProcessBeanDefinitionRegistry。
调用了BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
调用regularPostProcessors的postProcessBeanFactory
registerBeanPostProcessors.
新建一个BeanPostProcessorChecker
实现了PriorityOrdered接口的BeanPostProcessor 添加进入priorityOrderedPostProcessors列表,
实现了Ordered接口没有实现PriorityOrdered的BeanPostProcessor进入orderedPostProcessorNames
其余的进入nonOrderedPostProcessorNames。
注册priorityOrderedPostProcessors中的BeanPostProcessor。
遍历orderedPostProcessorNames,其中实现了MergedBeanDefinitionPostProcessor接口的进入internalPostProcessors,其余的进入orderedPostProcessors
注册orderedPostProcessors中的后处理器
遍历nonOrderedPostProcessorNames,其中实现了MergedBeanDefinitionPostProcessor接口的进入nonOrderedPostProcessors,其余的进入orderedPostProcessors
注册nonOrderedPostProcessors中的后处理器
注册internalPostProcessors中的后处理器
注册就是在BeanFactory中的beanPostProcessors列表去除旧的对象(也是自己),添加新的对象(也是自己)
initMessageSource
用于国际化
首先确认是否有LocalBean:MessageSource
在 Spring 中,本地 Bean(Local Bean)是指在当前容器中定义和注册的 Bean,即在同一个容器中创建和管理的 Bean。本地 Bean 是指在同一个 Spring 容器中定义的 Bean,可以通过容器的上下文(ApplicationContext)来获取和管理。
与本地 Bean 相对的是外部 Bean(External Bean),外部 Bean 是指在另一个容器中定义和管理的 Bean。在 Spring 中,可以通过依赖注入(Dependency Injection)或者通过 JNDI 查找等方式来获取外部 Bean。
本地 Bean 的特点包括:
- 本地 Bean 是在同一个容器中定义和注册的,可以直接通过容器的上下文来获取和管理。
- 本地 Bean 的生命周期受容器管理,容器负责创建、初始化、销毁本地 Bean。
- 本地 Bean 可以通过容器的依赖注入功能来注入到其他 Bean 中,实现 Bean 之间的依赖关系。
本地bean的定义,gpt给出。feign调用好像算外部bean?
获取MessageSource bean ,如果这个bean是HierarchicalMessageSource
设置ParentMessageSource
bean直接放入三级缓存。
initApplicationEventMulticaster
初始化此上下文的事件多播程序。
事件多播程序负责管理事件的发布,用来进行广播。
首先确认是否有LocalBean:applicationEventMulticaster
设置时间多播程序,beanFactory的ApplicationEventMulticaster
onRefresh
可以重写以添加特定于上下文的刷新工作。在实例化单例之前调用特殊 Bean 的初始化
registerListeners
注册事件的监听器
给applicationEventMulticaster设置监听器
获取实现applicationEventMulticaster接口的beanName
finishBeanFactoryInitialization
实例化除了懒加载外的所有bean。
实例化一个bean,首先获取bean对应的BeanDefinition。然后尝试getBean。
getBean调用doGetBean,首先会去三重缓存中尝试获取bean。获取到bean就说明这个bean实例化过了。
获取不到bean,就会开始实例化该bean。
通过反射获取bean的构造器并进行实例化,产生半成品bean
把beanName和获取半成品bean的lamda表达式放入singletonFactories map中
开始进行属性注入
通过beanName去getBean(这里开始套娃)。初始化bean之前bean中的所有属性都要实例化过。
如果发生循环依赖可以参考我之前写的循环依赖博客。
此时bean初始化结束。getBean返回了bean
最后只会在第一层缓存中保存实例化初始化结束的bean
finishRefresh
清除上下文中的资源缓存
初始化LifecycleProcessor。
实现LifecycleProcessor接口的onRefresh可以在spring的refresh方法结束后进行某些操作。实现onClose方法,可以在context关闭后实现某些方法。
比如说可以在onRefresh方法实现资源的创建,比如说和数据库进行连接,可以在onClose方法中进行资源的释放,如数据库连接的释放
调用LifecycleProcessor的onRefresh
发布ContextRefreshedEvent时间,表示Refresh结束
resetCommonCaches
重置某些缓存,例如spring通过反射获取的信息,在创建完bean后不会在用到了,就可以清除了。