Spring源码解析二十

上一篇中,我们了解了spring中是如何基于事件驱动开发的,其实就是将监听器注册到事件广播器中,然后当spring发布事件时,事件广播器会遍历所有注册的监听器,并通过监听该事件的监听器来处理事件。这一篇中,我们继续将下面的方法:
在这里插入图片描述
我们进到onRefresh方法中看下:
在这里插入图片描述
可以看到方法onRefresh也是一个空方法,这个也是通过关键词protected修饰了,也就是说该方法onRefresh也是Spring留给子类的一个扩展方法。我们继续往下看:
在这里插入图片描述
我们进到这个registerListener方法中看下:
在这里插入图片描述
这个方法就是将参数中的监听器以及spring容器中获取到的监听器,分别注册到广播器中。所以为什么我们上一篇中,可以通过广播器获取到这些监听器了。
我们在看下refresh中其他的方法:
在这里插入图片描述
我们先看下这个finishRefresh方法,我们跟进去看下:
在这里插入图片描述
这个里面主要是初始化和生命周期相关的一些组件,我们可以先到方法initLifecycleProcessor中看下:
在这里插入图片描述
可以看到方法在initLifecycleProcessor中,首先就是到spring容器中看下是否存在名称lifecycleProcessor的bean。如果存在的话,就直接从spring容器中获取出来,并且赋值给成员变量lifecycleProcessor,如果不存在的话默认会创建一个DefaultLifecycleProcessor类型的对象,并且赋值给成员变量lifecycleProcessor,最后注入到spring容器中,那这个DefaultLifecycleProcessor又是什么呢?其实DefaultLifecycleProcessor在spring中,出来spring声明周期相关的一个组件,spring提供声明周期的接口Lifecycle,我们可以通过这个DefaultLifecycleProcessor类图看下:
在这里插入图片描述

可以看到,DefaultLifecycleProcessor最终实现的接口Lifecycle的,而LifecycleProcessor接口也只不过是Lifecycle接口的一个扩展接口而已,我们看下这个两个接口的方法:
在这里插入图片描述
在spring中如果bean实现了接口Lifecycle,spring会保证在容器启动时,就会调用这些bean中的start方法开启它们的声明周期,当然,在spring关闭的时候也会调用stop方法来结束它们的声明周期。而LifecycleProcessor在Lifecycle的基础上又添加了两个方法onRefresh和OnClose,主要就是对bean的状态进行更新,我们可以看下这个方法:
在这里插入图片描述
我们进入到方法中:
在这里插入图片描述
在这里插入图片描述
可以看到在onRefresh方法中,会从spring容器中获取所有实现了Lifecycle接口的bean,然后调用start方法来开启它们的声明周期。

最后,我们看下finishRefresh最后的一些逻辑:
在这里插入图片描述
可以看到,其实就是发布了一个刷新上下文的事件ContextRefreshedEvent,我们可以获取到这个事件进行相应的操作,比如系统启动时执行一些定时任务。

我们最后看下refresh的一个非常关键的方法:
在这里插入图片描述
这个finishBeanFactoryInitialization 方法非常的重要,接下来我们都是围绕这个方法讲的。我们先简单到这个方法里面看下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 1、从spring容器 beanFactory中获取ConversionService对应的bean并且初始化它
		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.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		// 获取spring容器中beanFactory中,实现接口LoadTimeWeaverAware的bean名称
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			// 提前调用getBean方法,尽早的初始化这些名称对应的bean
			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();
	}

可以看到,在finishBeanFactoryInitialization方法中,其实初始化了一下bean,我们重点的看下beanFactory调用的方法preInstantiateSingletons:
在这里插入图片描述
我们进到方法看下:
在这里插入图片描述
可以看到,在方法preInstantiateSingletons中,首先会遍历所有注册到spring容器中的BeanDefinition,如果BeanDefinition的属性scope的值为singleton也就是单例的,同时属性lazyInit的值wei false,说明该BeanDefinition对应的bean是不允许懒加载的单例bean。既然bean不允许懒加载,那当然就要立马去加载它了,所以,我们可以看到接下来就会调用getBean方法去实例化bean了。

我们先总结一下今天的内容:
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youngerone123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值