Spring源码私家笔记—— ApplicationContext.refresh()方法浅析

从本章开始我们将开始进入Spring容器真正的刷新启动过程,直接点击或者debugger进入AbstractApplicationContextrefresh()方法。这里再次提示一下大家,在先前的提到过的“胸有大纲,心中不慌”,大家务必要克制自己挨个debugger进refresh的每个方法进行查看的冲动。

大家想啊,Spring的作者把一个个的对象和方法封装出来,就是想要屏蔽底层实现的复杂性,那我们就按照这一个个方法名先理解个大概。建议大家直接把springframework的官方源码clone下来,在分析源码的过程中,尽情的把自己的理解和疑问以注释的形式,写到源码当中去,这就好比读一本书,只有有了自己的理解和感想,这本书才会被读者赋予它的灵魂。

下面笔者就打个样。进入refresh()方法,看看Spring容器是咋刷新的。

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			/*
			 * Prepare this context for refreshing, setting its startup date and
			 * active flag as well as performing any initialization of property sources.
			 * 容器刷新前的准备工作
			 * 1. 设置启动时间、激活/关闭标志位,
			 * 2. 执行属性资源的初始化验证必须的属性
			 * 3. 进行监听器和监听事件集合初始化
			 */
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 获取BeanFactory对象,同时还进行了BeanDefinition信息的加载
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			/*
			 * Configure the factory's standard context characteristics,
			 * such as the context's ClassLoader and post-processors.
			 * 配置BeanFactory对象的一些属性,比如classLoader/一些BeanPostProcessor对象
			 * 特别像 ApplicationListenerDetector这个beanPostProcessor用来判断那些对象是否监听器对象
			 */
			prepareBeanFactory(beanFactory);

			try {
				/*
				 * Modify the application context's internal bean factory after its standard
				 * initialization. All bean definitions will have been loaded, but no beans
				 * will have been instantiated yet. This allows for registering special
				 * BeanPostProcessors etc in certain ApplicationContext implementations.
				 * 这是一个留给子类扩展的钩子,在beanFactory对象初始化好之后,注册一些额外的BeanPostProcessors等
				 */
				postProcessBeanFactory(beanFactory);

				/*
				 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
				 * respecting explicit order if given.
				 * <p>Must be called before singleton instantiation.
				 * 调用所有已注册的BeanFactoryPostProcessor对象的方法
				 */
				invokeBeanFactoryPostProcessors(beanFactory);

				/*
				 * Instantiate and register all BeanPostProcessor beans,
				 * respecting explicit order if given.
				 * <p>Must be called before any instantiation of application beans.
				 * 将BeanFactory中BeanPostProcessor类型的对象识别出来,并单独管理起来,
				 * 便于在Bean完成初始化之后进行使用
				 *
				 * Spring内部的一些特殊的Bean对象是早于自定义的Bean对象加入到容器工厂中的,
				 * 我们通常说的Bean的实例化和初始化是针对自定义Bean对象而言的
				 */
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 初始化用于国际化的资源
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化事件多播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 这是一个留给子类扩展的钩子,语义上是留给子类做一些额外的容器刷新工作,
				// 像SpringBoot就是扩展该方法启动一个TomcatServer和NettyServer
				onRefresh();

				// Check for listener beans and register them.
				// 注册监听器,所谓注册,其实是把容器中已有的监听器类型的Bean对象单独管理起来,
				// 以便于进行后续的管理及发挥其特殊的功能性
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有余下的非懒加载的单例Bean对象,字眼间有深意
				// 剩下的:Spring内置的Bean对象已经放到Bean工厂了,比如BeanFactoryPostProcessor/BeanPostProcessor/ApplicatinListener等
				// 非懒加载:懒加载的是在使用到的时候才生成(懒汉模式)
				// 单例:多例(prototype)的Bean对象是在使用到的时候生成
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			// 省略
		}
	}

单单从refresh()中调用的方法来讲,还是挺清楚的,当然我们也会看一下这些方法的声明注释,或者粗略的看一下里面的调用流程,但此时还是以理解大意为主,内部的实现有模糊有疑问的点可以先行跳过,或者通过注释留个标记。

方法名作用描述
prepareRefresh();容器刷新前的准备工作
beanFactory = obtainFreshBeanFactory()实例化BeanFactory对象,同时从Spring配置文件中解析加载所有的BeanDefinition对象
prepareBeanFactory(beanFactory)BeanFactory对象一些额外属性值设置
postProcessBeanFactory(beanFactory)BeanFactory对象已就位,留一个钩子给子类扩展用
invokeBeanFactoryPostProcessors(beanFactory)调用所有已注册的BeanFactoryPostProcessor对象的方法
registerBeanPostProcessors(beanFactory)将BeanFactory中BeanPostProcessor类型的对象识别出来,并单独管理起来,便于在Bean完成初始化之后进行使用
initMessageSource()初始化用于国际化的资源
initApplicationEventMulticaster()初始化事件多播器
registerListeners()注册监听器,所谓注册,其实是把容器中已有的监听器类型的Bean对象单独管理起来,以便于进行后续的管理及发挥其特殊的功能性
finishBeanFactoryInitialization(beanFactory)初始化所有余下的非懒加载的单例Bean对象
finishRefresh()

上述表格加粗的部分,我们将在后面的章节中着重进行解析,其他部分比如监听器、国际化等,我们将根据实际情况进行更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值