博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码 06 IOC refresh方法1
阅读量:37194 次
发布时间:2020-08-01

本文共 3326 字,大约阅读时间需要 11 分钟。

参考源

《Spring源码深度解析(第2版)》

版本

本文章基于 Spring 5.3.15


Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。

其中一共有 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);    }    @Override    protected 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();   }   return 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 {   @Override   public String getMessage() {      return "The following properties were declared as required but could not be resolved: " +            getMissingRequiredProperties();   }}

这里抛出的 MissingRequiredProperty 异常内容正对应了前面示例中报的异常

由此可见,刚才的异常正是由这里抛出的。

转载地址:http://xupwwy.baihongyu.com/

你可能感兴趣的文章
leetcode 热题 Hot 100-3. 合并两个有序链表
查看>>
leetcode 热题 Hot 100-4. 对称二叉树
查看>>
Leetcode C++《热题 Hot 100-12》226.翻转二叉树
查看>>
Leetcode C++《热题 Hot 100-13》234.回文链表
查看>>
Leetcode C++《热题 Hot 100-14》283.移动零
查看>>
Leetcode C++《热题 Hot 100-15》437.路径总和III
查看>>
Leetcode C++《热题 Hot 100-16》448.找到所有数组中消失的数字
查看>>
Leetcode C++《热题 Hot 100-17》461.汉明距离
查看>>
Leetcode C++《热题 Hot 100-18》538.把二叉搜索树转换为累加树
查看>>
Leetcode C++《热题 Hot 100-19》543.二叉树的直径
查看>>
Leetcode C++《热题 Hot 100-21》581.最短无序连续子数组
查看>>
Leetcode C++《热题 Hot 100-22》2.两数相加
查看>>
Leetcode C++《热题 Hot 100-23》3.无重复字符的最长子串
查看>>
Leetcode C++《热题 Hot 100-24》5.最长回文子串
查看>>
Leetcode C++《热题 Hot 100-26》15.三数之和
查看>>
Leetcode C++《热题 Hot 100-27》17.电话号码的字母组合
查看>>
Leetcode C++《热题 Hot 100-28》19.删除链表的倒数第N个节点
查看>>
Leetcode C++《热题 Hot 100-29》22.括号生成
查看>>
Leetcode C++《热题 Hot 100-30》31.下一个排列
查看>>
Leetcode C++《热题 Hot 100-40》64.最小路径和
查看>>