spring源码阅读(二)--ioc容器加载(一)--prepareRefresh();

废话不多说,直接开始上源码

ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext(“classpath:spring.xml”);

	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		//这个super方法会连续调用三次父类构造器,目的就是为了初始话父类,和获取资源加载器,和设置父子容器
		super(parent); 
		// 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

继续跟进super方法可得

	/**
		 * 这个this() 主要就是初始化资源加载器
		 * 	public AbstractApplicationContext() {
		 * 		this.resourcePatternResolver = getResourcePatternResolver();
		 *        }
		 */
		this();
		//设置父子容器,
		setParent(parent);

最最重点的方法来了,refresh(); 该方法体现了整个ioc容器的生命周期

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//准备刷新上下文环境
			prepareRefresh();

			// Tell the subclass to refresh the intern+al bean factory.
			//获取告诉子类初始化Bean工厂
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//对bean工厂进行填充属性
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//beanfactory后置处理器,留给子类去实现该接口
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//调用我们的bean工厂的后置处理器,1.将class扫描成bean定义,2.bean工厂的后置处理器调用
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation
				// 调用我们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也是从这个方法进行启动tomcat的
				onRefresh();

				// Check for listener beans and register them.
				//把我们的事件监听器注册到多播器上
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//实例化我们剩余的单例bean ----该方法体现bean的加载过程
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//最后容器创建完成,容器刷新,主要发布刷新事件(spring cloud也是从这里启动的)
				finishRefresh();
			}

首先分析一下prepareRefresh(),都准备了哪些上下文环境

	protected void prepareRefresh() {
		// 设置当前系统时间,
		this.startupDate = System.currentTimeMillis();
		//设置关闭状态false
		this.closed.set(false);
		//设置容器正在激活true
		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.
		/**
		 * 初始化资源加载器,空方法,用于子类扩展
		 * 	protected void initPropertySources() {
		 * 		// For subclasses: do nothing by default.
		 *        }
		 */
		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);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		//创建一个事件容器环境,注:earlyApplicationListeners是监听器容器,earlyApplicationEvents是事件容器
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

继续跟进validateRequiredProperties() 方法,可以看出主要是验证一些必要的属性是否为null

	@Override
	public void validateRequiredProperties() {
		MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
		for (String key : this.requiredProperties) {
			if (this.getProperty(key) == null) {
				ex.addMissingRequiredProperty(key);
			}
		}
		if (!ex.getMissingRequiredProperties().isEmpty()) {
			throw ex;
		}
	}

由于篇幅原因,这篇文章就先介绍到这里,太长太冗余,你们也没心思看,懂得都懂。下篇再往下讲,有讲的不对的,欢迎大家指出更正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值