Spring源码学习——AbstractApplicationContext

前言

在多次对Spring的源码断点调试以及了解ApplicationContext的结构之后,发现无论是ClassPathXmlApplicationContext还是FileSystemXmlApplicationContext的初始化最终会指向AbstractApplicationContext的**refresh()**方法。

AbstractApplicationContext是一个抽象类,这个类继承了DefaultResourceLoader类,实现了ConfigurableApplicationContext和DisposableBean这2个接口。为什么要使用抽象类呢?
我个人对于这种继承某个类,然后实现多个接口的做法的理解是通过使用抽象类提供默认的实现或者是公共的逻辑。

PS:本人学习的Spring源码版本为4.3.20.RELEASE,如果看到与文章内容不一致,可能是不同版本的实现方案不同


refresh()方法解读

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		//为Context的刷新准备
		prepareRefresh();
		
		//让子类刷新内部的BeanFactory,其实就是让子类调用refreshBeanFactory()方法的地方
		//refreshBeanFactory()是个抽象方法,需要子类实现
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		//准备用于Context的BeanFactory
		prepareBeanFactory(beanFactory);

		try {
			//允许在AbstractApplicationContext的子类中对BeanFactory进行后置处理。
			//postProcessBeanFactory()方法是个空实现
			postProcessBeanFactory(beanFactory);

			//调用BeanFactory的后置处理器处理BeanFactory实例
			invokeBeanFactoryPostProcessors(beanFactory);

			//将Bean的后置处理器注册到上下文(Context)的BeanFactory实例
			//Bean的后置处理器是用于拦截Bean的创建,并对创建后的Bean实例进行处理
			registerBeanPostProcessors(beanFactory);

			//初始化上下文的消息资源
			initMessageSource();

			//初始化应用上下文的事件接收器
			//表明Spring内部是基于事件机制
			initApplicationEventMulticaster();

			//这个方法是空实现,允许在AbstractApplicationContext的子类重写
			onRefresh();

			//检查监听器Bean并将这些Bean实例注册到上下文
			registerListeners();

			//初始化所有非懒加载的单例对象
			finishBeanFactoryInitialization(beanFactory);

			//发布容器刷新完成事件,完成刷新过程
			finishRefresh();
		}

		catch (BeansException ex) { //捕获BeansException
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			//销毁所有已经创建的单例对象,避免Bean资源占用
			destroyBeans();

			//取消刷新,重置active标识(置为false)
			cancelRefresh(ex);

			//将异常传给调用者
			throw ex;
		}

		finally {
			//重置Spring中内置的自检缓存,其实就是清空缓存
			resetCommonCaches();
		}
	}
}

心得体会

  1. Spring中的BeanFactory算不算是Spring的Bean呢?
    BeanFactory算Spring的Bean,不过BeanFactory是先初始化之后再注册到Spring的上下文,虽然BeanFactory本身也是Spring上下文的一部分。详情可以参考AbstractApplicationContextrefresh方法中调用的prepareBeanFactory、postProcessBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors这几个方法。

  2. Spring的上下文初始化的时候只会初始化非懒加载的单例对象(参考finishBeanFactoryInitialization()方法),这是因为懒加载的单例对象本身就应该在使用到的时候才进行初始化,而多例对象则是会在调用BeanFactory.getBean()方法时创建一个新的实例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值