spring 源码通过xml方式容器刷新前的准备

本文探讨了Spring框架的两大核心组件——DefaultSingletonBeanRegistry和ApplicationContext,详细阐述了容器初始化的过程,包括prepareRefresh()的启动准备、refreshBeanFactory()的容器构建以及loadBeanDefinitions()的Bean定义加载。通过ClassPathXmlApplicationContext的实例,揭示了Spring如何从XML解析到创建和刷新容器的详细步骤,为深入理解Spring的内部工作机制提供了基础。

简介

spring大体可以分为两个路线,一个是容器(DefaultSingletonBeanRegistry),一个是应用上下文(ApplicationContext),它们都是子BeanFactory的实现

  1. DefaultSingletonBeanRegistry 用于缓存bean定义信息及bean
  2. ApplicationContext 上下文,用于保存spring应用过程的信息

接下来是以XML解析的方式深入探索

源码还没有构建的可以参考
在这里插入图片描述

ClassPathXmlApplicationContext xml解析应用上下文

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
	//指定父容器
	super(parent);
	//设置加载文件
	setConfigLocations(configLocations);
	if (refresh) {
		//开始刷新容器
		refresh();
	}
}

refresh() 开始刷新容器

刷新容器基本包括这些步骤

  1. 获得容器
  2. 加载Bean定义信息(创新Bean必要的信息)
  3. 执行BFPP(Bean定义信息后置处理器)
  4. 注册BFPP(Bean的后置处理器)
  5. Bean的实例化
  6. 填充属性
  7. 执行Aware接口
  8. 执行BPP before方法
  9. 初始化
  10. 执行BPP after方法
  11. 销毁bean

那么咱们先看下获得容器

prepareRefresh(); 启动容器前准备

启动前准备有这几个作用

  1. 设置启动时间
  2. 设置启动和关闭标识
  3. 准备环境
  4. 准备应用监听及事件
// AbstractApplicationContext.prepareRefresh
protected void prepareRefresh() {
	// Switch to active.
	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());
		}
	}
	//供子类扩展
	initPropertySources();
	//准备环境
	getEnvironment().validateRequiredProperties();
	//准备应用监听及事件
	if (this.earlyApplicationListeners == null) {
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
	}
	else {
		this.applicationListeners.clear();
		this.applicationListeners.addAll(this.earlyApplicationListeners);
	}
	this.earlyApplicationEvents = new LinkedHashSet<>();
}

obtainFreshBeanFactory 获取容器

容器刷新主要做了这些事情

  1. 获得一个新的容器
  2. 设置容器表示
  3. 定制化工厂(属性覆盖,循环依赖)
  4. 加载Bean定义信息
protected final void refreshBeanFactory() throws BeansException {
	//存在bean工厂销毁
	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	try {
		//获取新的工厂
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		//设置标示
		beanFactory.setSerializationId(getId());
		//定制化工厂(是否允许属性覆盖,是否允许循环依赖)
		customizeBeanFactory(beanFactory);
		//加载bean的定义信息
		loadBeanDefinitions(beanFactory);
		this.beanFactory = beanFactory;
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}

加载Bean定义信息是Spring中非常重要的环节,咱们下篇深入了解loadBeanDefinitions(beanFactory)方法实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值