spring ioc源码-refresh();
2023-12-31 23:51:14
主要作用是刷新应用上下文
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 启动刷新的性能跟踪步骤
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备刷新,设置标志位,保存了容器的启动时间
prepareRefresh();
// 子类实现,获取一个新的 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备 BeanFactory,设置一些基本的配置
prepareBeanFactory(beanFactory);
try {
// 允许子类对 BeanFactory 进行进一步的处理
postProcessBeanFactory(beanFactory);
// 启动性能跟踪步骤,执行在容器中注册的 BeanFactoryPostProcessors
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessors,这些 processors 会拦截 Bean 的创建过程
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 初始化消息源
initMessageSource();
// 初始化事件广播器
initApplicationEventMulticaster();
// 子类实现,初始化一些特殊的 beans
onRefresh();
// 注册监听器 beans
registerListeners();
// 实例化所有剩余的(非懒加载的)单例 beans
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例 beans,以避免悬空资源
destroyBeans();
// 重置 'active' 标志位
cancelRefresh(ex);
// 将异常传播给调用者
throw ex;
} finally {
// 重置 Spring 核心中的常见内省缓存,因为我们可能不再需要单例 beans 的元数据了
resetCommonCaches();
// 结束性能跟踪步骤
contextRefresh.end();
}
}
}
主要就做了这些,对上面的方法进行分解:
prepareRefresh():
主要就是保存了启动时间,启动标志
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
//....省略部分代码
}
prepareBeanFactory??
做准备工作
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//添加后置处理器:ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略自动装配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
//以下接口,允许自动装配,第一个参数是自动装配的类型,,第二个字段是自动装配的值
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as
//添加一个后置处理器:ApplicationListenerDetector,此后置处理器实现了BeanPostProcessor接口
ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && 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.
//在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
invokeBeanFactoryPostProcessors(beanFactory);
主要逻辑代码在org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
代码设计太多就不粘贴了,主要做了一下逻辑:
-
初始化设置:
- 该方法接收一个
ConfigurableListableBeanFactory
和一个BeanFactoryPostProcessor
实例的列表。
- 该方法接收一个
-
处理
BeanDefinitionRegistryPostProcessor
实例:- 如果
beanFactory
也是BeanDefinitionRegistry
(用于管理 bean 定义的扩展接口),则该方法区分常规的BeanFactoryPostProcessors
和实现了BeanDefinitionRegistryPostProcessor
的处理器。 - 它遍历提供的
beanFactoryPostProcessors
,对于实现了BeanDefinitionRegistryPostProcessor
接口的实例,调用其postProcessBeanDefinitionRegistry
方法,并将它们收集到不同的列表中。
- 如果
-
按顺序处理
BeanDefinitionRegistryPostProcessor
:- 该方法按照三个阶段处理
BeanDefinitionRegistryPostProcessor
:PriorityOrdered、Ordered 和其他处理器。 - 对于每个阶段,它获取相关的后置处理器名称,实例化它们,根据它们的优先级或顺序排序,并调用它们的
postProcessBeanDefinitionRegistry
方法。
- 该方法按照三个阶段处理
-
处理已注册的
BeanFactoryPostProcessor
实例:- 如果
beanFactory
不是BeanDefinitionRegistry
,则直接调用已注册的BeanFactoryPostProcessor
实例。
- 如果
-
按顺序处理
BeanFactoryPostProcessor
:- 该方法根据实现
PriorityOrdered
、Ordered
和其他接口的BeanFactoryPostProcessor
分别处理。 - 首先,调用实现了
PriorityOrdered
接口的后置处理器。 - 接着,调用实现了
Ordered
接口的后置处理器。 - 最后,调用所有其他
BeanFactoryPostProcessor
。
- 该方法根据实现
-
清除缓存的合并 bean 定义:
- 由于后置处理器可能已修改原始元数据,例如替换值中的占位符,因此清除缓存的合并 bean 定义。
文章来源:https://blog.csdn.net/qq_31273845/article/details/135170143
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!