springboot的启动分为两部分,一部分是注解,一部分是SpringApplication.run(Springboot.class, args),那么我们的注解又是如何嵌入到程序中呢?靠的就是refreshContext方法,同理,我们跟踪源码进入refreshContext方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备这个上下文来刷新。
//记录启动时间、状态,web容器初始化其property,复制listener
prepareRefresh();
// 告诉子类刷新内部bean工厂。
//这里返回的是context的BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//beanFactory注入一些标准组件,例如ApplicationContextAwareProcessor,ClassLoader等
// 准备bean在此上下文中使用。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理。
//给实现类留的一个钩子,例如注入BeanPostProcessors,这里是个空方法
postProcessBeanFactory(beanFactory);
// 调用在上下文中注册为bean的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean处理器。
registerBeanPostProcessors(beanFactory);
// 初始化此上下文的消息源。
initMessageSource();
// 为此上下文初始化事件多播。
initApplicationEventMulticaster();
// 在特定的上下文子类中初始化其他特殊bean。
onRefresh();
// 检查侦听器bean并注册它们。
registerListeners();
// 实例化所有剩余的(非拉齐-init)单例。
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应事件.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例以避免悬空资源。
destroyBeans();
// 重置“actiove”标志。
cancelRefresh(ex);
// 向调用者传播异常。
throw ex;
}
finally {
// 重置Spring核心中常见的内省缓存,因为我们可能不再需要单例bean的元数据了。。。
resetCommonCaches();
}
}
}
到这里,就可以看到一系列bean的操作,继续跟踪进入invokeBeanFactoryPostProcessors(调用在上下文中注册为bean的工厂处理器)方法
进入ConfigurationClassParser这个类后,方法调用也是挺绕的,这里就不深究了…进入这个类主要是想看下它的一些方法,因为对于springboot注解的引用就是在这个类进行的,比如doProcessConfigurationClass:
标签:初始化,SpringBoot,beanFactory,refreshContext,子类,bean,图看,ex,上下文 From: https://blog.csdn.net/zhyooo123/article/details/143225517