Spring源码 06 IOC refresh方法1
Spring IOC 的核心是
AbstractApplicationContext
的refresh
方法。
其中一共有 13 个主要方法,这里分析第 1 个:prepareRefresh
。
1 AbstractApplicationContext
1-1 刷新前的准备工作
prepareRefresh()
/** * 1 刷新前的准备工作 * 设置容器的启动时间 * 设置关闭状态为 false * 设置活跃状态为 true * 获取 Environment 对象,并加载当前系统的属性值到 Environment 对象中并进行验证 * 准备监听器和事件的集合对象,默认为空的集合 */protected void prepareRefresh() {// 设置容器启动时间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.applicationListeners 为空,SpringBoot 中则有值 this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else { // 如果不等于空,则清空集合元素对象 this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners);}// 创建刷新前的监听事件集合this.earlyApplicationEvents = new LinkedHashSet<>();}
1-2 初始化属性资源
initPropertySources()
protected void initPropertySources() { }
这里该方法为空,是为了留给子类扩展使用。
扩展
添加必需属性验证
如果在使用 Spring 容器时某些属性是必需的,可以用扩展 initPropertySources()
的方式实现验证。
编写自定义类继承
ClassPathXmlApplicationContext
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {public MyClassPathXmlApplicationContext(String... configLocations) {super(configLocations);}@Overrideprotected void initPropertySources() { System.out.println("扩展了initPropertySources");// 添加验证要求getEnvironment().setRequiredProperties("VAR");}}
使用自定义类
ApplicationContext context = new MyClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = context.getBean(UserDao.class);userDao.add();
运行结果
因为添加了 VAR 为必需属性,而环境中找不到该属性,所以报错。
1-2 获取环境信息
getEnvironment()
public ConfigurableEnvironment getEnvironment() {if (this.environment == null) { // 创建环境对象 this.environment = createEnvironment();}retu this.environment;}
由于前面对 environment
赋值了,这里就直接返回 environment
。
1 AbstractApplicationContext
1-2 验证必需的属性
validateRequiredProperties()
2 AbstractEnvironment
public void validateRequiredProperties() throws MissingRequiredPropertiesException { // 验证必需的属性this.propertyResolver.validateRequiredProperties();}
3 AbstractPropertyResolver
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;}}
这里主要对必需的属性做验证,没有则抛出对应异常。
public class MissingRequiredPropertiesException extends IllegalStateException {@Overridepublic String getMessage() { retu "The following properties were declared as required but could not be resolved: " +getMissingRequiredProperties();}}
这里抛出的
MissingRequiredProperty
异常内容正对应了前面示例中报的异常
由此可见,刚才的异常正是由这里抛出的。
参考
https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click
https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0
《Spring源码深度解析(第2版)》
版本
Spring 5.3.15
本文来自博客园,作者:程序航,转载请注明原文链接:https://www.cnblogs.com/codesail/p/15951064.html
作者:程序航
来源链接:https://www.cnblogs.com/codesail/p/15951064.html
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。