Spring源码之refresh
1.refesh的核心介绍
在 Spring 框架中,refresh
主要用于刷新应用上下文。这一过程涉及多个重要的步骤,确保 Spring 容器的状态更新、bean 的加载以及资源的初始化。
refresh
方法的主要功能
-
初始化上下文:
refresh
方法会初始化应用上下文,加载和配置所有的 bean,包括从配置文件、注解、XML 等中定义的 bean。 -
注册后处理器:
在刷新过程中,Spring 会注册各种后处理器(如BeanPostProcessor
和BeanFactoryPostProcessor
),这些后处理器可以对 bean 的创建过程进行干预。 -
执行初始化逻辑:
对于那些标记了@PostConstruct
或实现了InitializingBean
接口的 bean,Spring 会在此阶段调用它们的初始化方法。 -
创建和注册 bean:
在刷新过程中,Spring 会创建所有单例 bean 的实例并将其注册到应用上下文中。这包括处理依赖注入和自动装配。 -
处理生命周期事件:
在上下文刷新期间,Spring 会触发相应的生命周期事件,如ContextRefreshedEvent
,让其他组件可以监听这些事件并执行特定操作。
2.register源码
处理 bean 的定义、作用域、注解等信息,并将其注册到 Spring 的 bean 注册表中。AnnotatedBeanDefinitionReader#doRegisterBean()
3.refresh源码
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 这里会判断能否刷新,并且返回一个BeanFactory, 刷新不代表完全情况,主要是先执行Bean的销毁,然后重新生成一个BeanFactory,再在接下来的步骤中重新去扫描等等
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备BeanFactory
// 1. 设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器
// 2. 添加三个BeanPostProcessor,注意是 具体的BeanPostProcessor实例对象
// 3. 记录ignoreDependencyInterface
// 4. 记录ResolvableDependency
// 5. 添加三个单例Bean
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 子类来设置一下BeanFactory
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
// 默认情况下:
// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
invokeBeanFactoryPostProcessors(beanFactory); // scanner.scan()
// Register bean processors that intercept bean creation.
// 将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
// 设置ApplicationContext的MessageSource,要么是用户设置的,要么是DelegatingMessageSource
initMessageSource();
// Initialize event multicaster for this context.
// 设置ApplicationContext的applicationEventMulticaster,要么是用户设置的,要么是SimpleApplicationEventMulticaster
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 给子类的模板方法
onRefresh();
// Check for listener beans and register them.
// 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
3.1.首先是prepareRefresh方法
1.1initPropertySources模板方法,留给子类重写,
1.2validateRequiredProperties,从Environment中拿出key-value,包含系统环境变量和jvm环境变量,这个函数来验证目前需要使用到的key是否存在,如果不存在则报出异常。
说明:validateRequiredProperties
方法的主要作用是验证一组必需属性是否已被正确设置。通过抛出异常,它可以有效地提醒开发者或运维人员缺失的配置,从而提高应用的健壮性和可靠性。
1.3设置成员属性,主要是监听器。
// Initialize any placeholder property sources in the context environment.
// 比如子类可以把ServletContext中的参数对设置到Environment
// 模板方法
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
3.2obtainFreshBeanFactory
这里会判断能否刷新,并且返回一个BeanFactory,刷新不代表完全情况。主要是先执行Bean的销毁,然后重新生成一个BeanFactory,再在接下来的步骤中重新去扫描等等。
对于SpringBoot,使用容器是AnnotationConfigApplicationContext,不能重复刷新;
对于SpringMVC,使用的是AnnotationConfigWebApplicationContext,可以重复刷新;
并且,这两个容器的初始化时机不同,SpringBoot在this中初始化容器,而SpringMVC是在刷新的时候进行初始化。
3.3prepareBeanFactory--准备BeanFactory
// Spring5.3中新增的功能,可以选择是否开启Spel功能,shouldIgnoreSpel默认为false,表示开启
if (!shouldIgnoreSpel) { // @Value(#{xxx})的解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 添加一个ResourceEditorRegistrar,注册一些级别的 类型转化器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 组成一个BeanPostProcessor,用来处理EnvironmentAware、EmbeddedValueResolverAware等回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
3.1拿到BeanClassLoader,我们可以自己给Bean工厂设置类加载器
3.2设置SpringEL的解析器,#{XXX}
3.3设置类型转换器ResourceEditorRegistrar,里面有很多转换器,比如Spring字符串-->File文件
3.4添加ApplicationContextAwareProcessor到BeanPostProcessor中,处理Aware的回调,它已经添加到BeanPostProcessor的list当中
比如,一个方法实现了Aware接口,那么在创建完bean的时候,就会调用方法中重写了接口的方法。
3.5ignoreDependencyInterface
将需要忽略的放入集合当中,在自动注入(依赖注入)的时候,如果类实现了这些接口,那么依赖注入就不会调用set方法执行,而只在最后执行一次set方法
3.6registerResolvableDependency
将这些东西直接注册为bean,类型对应
3.7添加ApplicationListenerDetector,它已经添加到BeanPostProcessor的list当中
这是监听器的BeanPostProcessor。
3.8判断是否有这些和环境变量相关的Bean。如果没有,那就给你添加bean到BeanFactory
包含系统环境变量、JVM环境变量、监控的对象。
3.4postProcessBeanFactory
这是一个模板方法
3.5.invokeBeanFactoryPostProcessors(内容很多,后面再讲)
扫描类,生成BeanDefinition,然后将BeanDefinition放到BeanFactory中
在执行这个方法之前,只是生成了BeanFactory容器自己需要用到的BeanDefinition,但是用户定义的类的BeanDefinition还没有生成,比如userService和orderService。
3.6.registerBeanPostProcessors
将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去,在Bean创建的时候会用beanPostProcessors。
3.7.initMessageSource
国际化
如果我们定义了messageSource名字的Bean,在这里就会将它设置为项目的国际化,否则使用spring默认的国际化工具。
3.8.initApplicationEventMulticaster
注册事件发布器,进行事件的发布。
如果程序员定义了那就用定义的,否则就用默认生成的发布器SimpleApplicationEventMulticaster
3.9.onRefresh
模板方法
3.10.registerListeners
注册监听器,将程序员定义好的监听器存储起来,设置到发布器的属性中去。
3.11.finishBeanFactoryInitialization,完成bean工厂的初始化!
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 如果BeanFactory中存在名字叫conversionService的Bean,则设置为BeanFactory的conversionService属性
// ConversionService是用来进行类型转化的
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 设置默认的占位符解析器 ${xxx} ---key
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化非懒加载的单例Bean
beanFactory.preInstantiateSingletons();
}
3.11.1ConversionService
设置一些类型转换器的Bean
3.11.2设置默认的占位符解析器,${XXX},解析Environment的key-value
3.11.3 preInstantiateSingletons,实例化非懒加载的单例Bean,bean生命周期的入口!!!重点!!后面会详细讲!
3.12.finishRefresh
3.12.1initLifecycleProcessor();
和Spring容器的生命周期有关。我们可以实现smartLiftcycle接口,然后重写start,stop,running方法,检测Spring容器的生命周期。
3.12.2publishEvent
发布 容器启动完成的事件
4.invokeBeanFactoryPostProcessors
作用:生成BeanDefinition,将BeanDefinition注册到bean工厂中,其中包括相关配置类、userService(程序员自己定义的)等全部定义的bean。
核心方法是invokeBeanFactoryPostProcessors,其中一个入参为List<BeanFactoryPostProcessor> beanFactoryPostProcessors,它主要包含两个部分:BeanFactoryPostProcessor(后执行)和BeanDefinitionRegistryPostProcessor(先执行)(可以注册新的beanDefinition)
postProcessBeanDefinitionRegistry:可以注册新的beanDefinition,创建beanDefinition;
postProcessBeanFactory:只能修改beanDefinition,增强beanDefinition;
postProcessBeanDefinitionRegistry继承postProcessBeanFactory!
1.1先执行通过ApplicationContext.add添加进来的BeanDefinitionRegistryPostProcessor 的
postProcessBeanDefinitionRegistry()方法。
这个方法中有个重要的方法processConfigBeanDefinitions,它会解析定义的配置类,生成所有BeanDefinition。
// beanFactoryPostProcessors集合一般情况下 都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法添加了
// beanFactoryPostProcessors中可能包含了:普通BeanFactoryPostProcessor对象和BeanDefinitionRegistryPostProcessor对象
// 对于BeanDefinitionRegistryPostProcessor对象,会执行自己的postProcessBeanDefinitionRegistry()方法
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);// 先执行postProcessBeanDefinitionRegistry方法
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
1.2 getBeanNamesForType
拿到的类型是BeanDefinitionRegistryPostProcessor
先将拿到的ConfigurationClassPostProcessor(配置类的PostProcessor)加入list
1.3核心:然后按顺序,顺序为实现了PriorityOrdered接口、Ordered接口、自定义的PostProcessor的postProcessBeanDefinitionRegistry()方法。(按顺序去将实现了PriorityOrdered、Ordered接口的类,生成BeanDefinition)
1.4核心:然后开始执行postProcessBeanFactory,也是按顺序执行,依次执行子接口的方法、实现了PriorityOrdered接口、Ordered接口、自定义的PostProcessor的postProcessBeanFactory()方法。(增强BeanDefinition,修改属性)
使用:我们可以自定义实现BeanFactoryPostProcessor接口或者它的子类BeanDefinitionRegistryPostProcessor,重写他们的方法。子类可以新增BeanDefinition,父类可以增强或者修改BeanDefinition的一些属性
5.registerBeanPostProcessors
作用:将扫描到的BeanPostProcessors实例化并排序,添加到BeanFactory的beanPostProcessors属性中去。(添加BeanPostProcessor到BeanPostProcessors中,创建bean的时候使用它)
循环、排序、加到beanPostProcessors的list中!
1.getBeanNamesForType
首先,拿到BeanPostProcessors类型的Bean(也就是拿到所有的BeanPostProcessor)
2.分类
根据实现的接口类型,进行分类。(PriorityOrdered、Ordered、其他)
3.排序
根据实现的接口类型,进行排序。(PriorityOrdered、Ordered、其他)
4.添加到list当中(其中实现了MergedBeanDefinitionPostProcessor接口的BeanPostProcessor放到list的最后面,意思可能是用户定义的先放(用户的优先级较高),然后存放容器提供的)
list指的是存放BeanPostProcessor(后置处理器)的集合,在创建Bean的时候,会经常用到这个list。
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();