Spring refresh 方法详解
对应上一章的流程梳理,这里定位到源码中看看 Spring 中 bean 创建的具体流程。
本来是想梳理 refresh
的整个流程,但是发现太长了,于是只好缩小目标,这一章的目标是 把 Spring
中 Bean 创建
这一步的流程给梳理明白了。
但是整个线索还是 AbstractApplicationContext
中的 refresh
方法,这个方法作为贯穿整个过程的线索。
流程图:
这里仍然可以参考 Spring IoC 工作流程梳理 这一章的内容,具体来说图还是这张,只是我们的关注点在于 BeanFactory
自己的初始化,以及初始化之后怎样创建 XML
中我们定义的 Bean
实例。
也就是我们本章的内容只到红框中的部分为止:
Spring Bean 创建具体执行流程源码追踪与梳理:
refresh 流程图 从初始化 BeanFactory 到 Bean 实例创建结束
起点:
org.springframework.context.support.AbstractApplicationContext
refresh()
方法 是 Spring
容器的核心方法,这里是入口,也是容器真正初始化的地方。
由于 refresh
的重要性,所以这里我搬运了完整的代码,并添加了一些注释,后续的代码可能我会只截取最重要的部分,因为如果完整搬运的话,太长了,并且无法突出重点。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备上下文环境
prepareRefresh(); // ①
// Tell the subclass to refresh the internal bean factory.
// 创建并初始化 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // ②
// Prepare the bean factory for use in this context.
// 填充 BeanFactory 功能,使其可用
prepareBeanFactory(beanFactory); // ③
try {
// Allows post-processing of the bean factory in context subclasses.
// 提供子类覆盖的额外处理,即子类自己的扩展点BeanFactoryPostProcessor
postProcessBeanFactory(beanFactory); // ④
// Invoke factory processors registered as beans in the context.
// 激活BeanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory); // ⑤
// Register bean processors that intercept bean creation.
// 注册拦截Bean创建的处理器,注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory); // ⑥
// i18n 国际化相关处理
initMessageSource(); // ⑦
// 广播器的注册
initApplicationEventMulticaster(); // ⑧
// 另一个模板方法的应用,空实现,交给子类自己处理
onRefresh(); // ⑨
// 绑定监听器,为后续的监听事件回调做准备
registerListeners(); // ⑩
// Instantiate all remaining (non-lazy-init) singletons.
// 真正对 Bean 进行实例化的地方,初始化所有非懒加载的单例对象
finishBeanFactoryInitialization(beanFactory); // 11
// Last step: publish corresponding event.
finishRefresh(); // 12
}
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();
}
}
}
1、创建 BeanFactory
对象 —— refresh()#prepareRefresh();
// org.springframework.context.support.AbstractApplicationContext
// 完成准备工作,包括设置启动日期( startup date)
//活动标志(active flag)
//属性源的初始化工作( initialization of property sources.)
protected void prepareRefresh() {
// 设置启动时间,flag 初始化值
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
// 初始化某些资源
initPropertySources();
// 验证属性值
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
// 下面创建了一系列的 Set 集合(暂时忽略)
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);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2、obtainFreshBeanFactory —— 获取最新的 BeanFactory
,因为之前程序中可能已经存在 BeanFactory
。
// org.springframework.context.support.AbstractApplicationContext
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
// 跳转到 refreshBeanFactory 方法中,其具体实现类是 AbstractRefreshableApplicationContext
// org.springframework.context.support.AbstractRefreshableApplicationContext
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果已经存在 BeanFactory,则进行销毁
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 开始创建 BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 读取 BeanDefinition 信息
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
// org.springframework.context.support.AbstractRefreshableApplicationContext
// 创建默认的对象工厂 DefaultListableBeanFactory
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
读取 BeanDefinition
:
org.springframework.context.support.AbstractXmlApplicationContext
类中的 loadBeanDefinitions
方法,读取了 XML 中定义的 Bean 信息
可以看到在 AbstractRefreshableApplicationContext
中并没有实现 loadBeanDefinitions
方法,因为对应了不同的情况,这里我的 Bean
是定义在 XML
中的,所以我选择查看 AbstractXmlApplicationContext
中的实现
这一步执行完成之后, beanDefinitionMap
就有值了:
对应了我在 XML 中定义的 Bean
loadBeanDefinitions
执行完,这一步就完成了,返回了 refresh
() 的主流程。
3、 prepareBeanFactory —— 初始化 BeanFactory
,进行必须的赋值操作:
上一步 obtainFreshBeanFactory
完成之后 BeanFactory
已经创建好了,但是很多值还没有初始化,也就是还不是真正可用的状态,refresh
中下一步就是 prepareBeanFactory
对其进行初始化:
尚未初始化的 BeanFactory:可以看到有很多的 0
和 null
,这些都是默认值。
初始化完成后:
这一步并不复杂,只需要知道是初始化就行了,细节暂时不用深究。
4、postProcessBeanFactory —— 模板方法设计模式 ,预留的扩展点
// 模板方法,留给开发者需要做扩展的时候自己实现
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
可以看到,这里点进去之后并没有实现,这里就是一个模板,就是 BeanFactoryPostProcessor
,是 Spring
预留的扩展点。
Springboot
中就在对这个方法做出了扩展,如果需要进行扩展则由开发者自己进行实现。
5、 invokeBeanFactoryPostProcessors —— BeanFactoryPostProcessor 进行增强
对应源码位置:
org.springframework.context.support.AbstractApplicationContext
的 invokeBeanFactoryPostProcessors
方法
BeanFactoryPostProcessor 的功能对应流程图中的红框部分:
- 替换属性
- 修改 BeanDefinition
- ... 其他功能等
6、 registerBeanPostProcessors —— 绑定 BeanPostProcessor 处理器
这里的 BeanPostProcessor
和上一步的 BeanFactoryPostProcessor
并不是一个东西,希望大家不要混淆了,如图所示:
//org.springframework.context.support.AbstractApplicationContext
// 实例化并绑定 BeanPostProcessor ,并没有真正执行 BeanPostProcessor 中的代码
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
7、国际化处理 i 18n —— initMessageSource
非重要内容,暂时略过。
8、initApplicationEventMulticaster (重点) 初始化事件广播
用来发布处理后续发布的事件,与 Bean
的创建也无太大关系,略过。
9、onRefresh —— 又一个模板方法的扩展点
//org.springframework.context.support.AbstractApplicationContext
// 又是一个模板方法的扩展点,暂时略过
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
10、registerListeners 注册监听器
为了满足在 bean 创建过程中对事件的回调,先要将监听器和广播准备好。
11、 finishBeanFactoryInitialization —— 开始进行实例化工作(重点)
Instantiate all remaining (non-lazy-init) singletons.实例化所有非懒加载的单例对象
//org.springframework.context.support.AbstractApplicationContext
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 属性值的初始化 代码省略
...
// Instantiate all remaining (non-lazy-init) singletons.
// 关键在最后一句,开始初始化非懒加载的单例对象
beanFactory.preInstantiateSingletons();
}
点进 preInstantiateSingletons
方法,发现跳到了一个接口 : ConfigurableListableBeanFactory
,找到具体的实现: org.springframework.beans.factory.support.DefaultListableBeanFactory
这里可以看到 beanNames
这个 List
中保存的就是我们在 XML
中定义的 bean
的名称。
这里由于代码中嵌套的层级很深,所以我们仍然需要抓住重点:
- 找到
Spring
中具体创建对象的地方,也就是具体使用反射
的地方。
// org.springframework.beans.factory.support.DefaultListableBeanFactory
@Override
public void preInstantiateSingletons() throws BeansException {
// 加载完 XML 文件之后,所有定义的 Bean 都在这个列表中
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 循环实例化 beanNames 中对应的 bean 对象
for (String beanName : beanNames) {
// 获取 bean 描述信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 判断 bean 是否抽象、是否单例、是否懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否是 FactoryBean
// 代码忽略
else {
// 关键代码:获取 bean,跳入这个方法中
getBean(beanName);
}
}
}
// 还有一段循环,关系不大,所以忽略了。
}
跳入 getBean
方法中,创建 bean
的具体逻辑在这个方法里面:
// org.springframework.beans.factory.support.AbstractBeanFactory
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
这里重点又来了,源码中 do
开头的方法一般是真正的底层具体逻辑,所以进入 doGetBean
这个方法很长,直接来看关键代码:createBean
// org.springframework.beans.factory.support.AbstractBeanFactory
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons
// 判断是否是单例对象,第一次创建时对象不存在,所以 sharedInstance 为 null
Object sharedInstance = getSingleton(beanName);
// 如果是第一次创建的话, sharedInstance 为 null,所以下面的判断进不去
if (sharedInstance != null && args == null) {
// 代码省略...
}
try {
// 获取bean中的依赖信息
String[] dependsOn = mbd.getDependsOn();
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 关键代码,真正创建 bean 的地方,点进去。
return createBean(beanName, mbd, args);
}
// 下面的异常处理也不用看,只看重要的流程
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//... 还有一大段逻辑,与本次无关,直接忽略
}
点进 createBean
看具体实现:
// org.springframework.beans.factory.support.AbstractBeanFactory
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;
这里第一次跳进去是 AbstractBeanFactory
中的空实现,下一步就是找到其具体的实现类:
在 AbstractAutowireCapableBeanFactory
类中,实现了 createBean
的具体逻辑。
这个方法也很长,我们需要找到其核心的方法: do
开头的 doCreateBean
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 核心方法,主要看这里面的逻辑
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
下面看 doCreateBean
的具体代码:
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
// 这里只关注2个方法即可:createBeanInstance ——> 创建 bean , populateBean --> 填充bean
// 这里同样删除了大量代码,只找最主要的地方
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 创建一个 Bean 的包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 重点: 具体的实例化地方,跳入 createBeanInstance 方法中看细节
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
Object exposedObject = bean;
// 填充 bean 属性
populateBean(beanName, mbd, instanceWrapper);
return exposedObject;
}
createBeanInstance
:仍然不是最底层创建 bean 的地方,继续寻找。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Candidate constructors for autowiring?
// 关键点来了,这个方法的返回值是构造器
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// No special handling: simply use no-arg constructor.
// 继续跳入这个方法
return instantiateBean(beanName, mbd);
}
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 获取实例化策略
// 跳入 instantiate 中看细节
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
instantiate
已经接近 Spring 最底层使用 反射构造对象的地方了
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 跳入这里的具体逻辑中
return BeanUtils.instantiateClass(constructorToUse);
}
instantiateClass
—— 真正干活的地方
// org.springframework.beans.BeanUtils
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
// 真正使用反射创建对象的地方,就是这一行!
return ctor.newInstance(argsWithDefaultValues);
}
到这里 bean
的创建才算真正完成了: 我们寻寻觅觅,终于找到了真正干活的地方
下一步:填充 bean 属性(放到下一章去学习)
参考资料
马士兵 spring(p1 ~ p7 是我所梳理和添加的一些内容)
照着这个视频进行的梳理,自己修改了一下顺序,看起来更加自然。 最大的收获就是视频中老师所说的,看源码要有重点,奔着自己的目标,只梳理最主要的流程,不要每个方法都试图弄明白,那样很快会迷失在源码中。
我这次的目标就是梳理 Bean 创建的流程,我实现了,找到了 Spring 中具体创建 Bean 的地方。
希望你也有收获。
Q.E.D.
Comments | 0 条评论