Spring IOC refresh()方法——系统属性及环境变量的初始化以及验证

原创 2018年04月16日 16:14:36

prepareRefresh()方法主要做了哪些事情,例如对系统属性及环境变量的初始化以及验证。

protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();

    synchronized (this.activeMonitor) {
        this.active = true;
    }

    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }

    // Initialize any placeholder property sources in the context environment
    // 留给子类实现
    initPropertySources();

    // Validate that all properties marked as required are resolvable
    // 验证需要的属性文件是否都已经放入环境中
    // see ConfigurablePropertyResolver#setRequiredProperties
    getEnvironment().validateRequiredProperties();
}

(1)设置active 为true,这就是一个很简单赋值。
(2)initPropertySources看似没做什么事情,这个正式符合Spring开放式结构设计,给用户最大的扩展能力。用户根据自己的需要重写initPropertySources方法,并在方法中进行个性化的属性处理及设置。
(3)validateRequiredProperties是对属性进行验证,那么如何验证呢?

假如:现在有一个需求,工程在运行过程中用到的某个设置(比如VAR)是从系统环境变量取得的,而如果用户没有在系统环境变量中配置这个参数,那么工程可能不会工作。这要求可能会有各种各样的解决方法,当然,在Spring中可以这么做,你可以直接修改Spring的源码,例如修改ClassPathXmlApplicationContext。当然,最好的办法还是对源码进行扩展,我们可以自定义类:

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext{


    public MyClassPathXmlApplicationContext(String... configLocations) {
        super(configLocations);
    }


    @Override
    protected void initPropertySources() {
        //super.initPropertySources();
        getEnvironment().setRequiredProperty("VAR");
    }

}

我们自定义了继承自ClassPathXmlApplicationContext的MyClassPathXmlApplicationContext,并重写了initPropertySources方法,在方法中添加了我们的个性化需求,那么在验证的时候也就是程序走到getEnvironment().validateRequiredProperties()代码的时候,如果系统没有检测到对应VAR的环境变量,那么就抛出异常。当然我们还需要在使用的时候替换掉原有的ClassPathXmlApplicationContext,代码如下:

public class TestAnimal3 {
    public static void main(String[] args) {
        ApplicationContext context = new MyClassPathXmlApplicationContext("applicationContext.xml");
        Animal animal = (Animal) context.getBean("animal");  
        animal.say();
    }
}

看看控制台输出:

2018-04-16 16:23:04,426 [main] INFO  [com.feiniu.springframework.test.MyClassPathXmlApplicationContext org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:503)] - Refreshing com.feiniu.springframework.test.MyClassPathXmlApplicationContext@21b602b9: startup date [Mon Apr 16 16:23:04 GMT+08:00 2018]; root of context hierarchy
Exception in thread "main" java.lang.IllegalStateException: required key [VAR] not found
    at org.springframework.core.env.AbstractPropertyResolver.getRequiredProperty(AbstractPropertyResolver.java:94)
    at org.springframework.core.env.AbstractEnvironment.getRequiredProperty(AbstractEnvironment.java:444)
    at com.feiniu.springframework.test.MyClassPathXmlApplicationContext.initPropertySources(MyClassPathXmlApplicationContext.java:16)
    at org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:507)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:441)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    at com.feiniu.springframework.test.MyClassPathXmlApplicationContext.<init>(MyClassPathXmlApplicationContext.java:9)
    at com.feiniu.springframework.test.TestAnimal3.main(TestAnimal3.java:7)

从上述报错日志来看,required key [VAR] not found,找不到VAR变量,说明重写验证方法生效了。该功能可以运用到工作中的场景,在dev和beta环境配置文件都加了变量,由于开发人员疏忽,online环境配置漏了,此时测试人员验证功能也没覆盖到这段新增配置代码,就造成了online的bug。如果运用该功能,应用war包在online启动就会报错,以避免造成online的bug出现。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yp1125/article/details/79962131

The Dearbookian #20040617 - 转贴:谁谋杀了Wrox [by gigix]

The Dearbookian #20040617谁谋杀了Wrox by gigix 此文已经发表在作者的专栏上面:http://www.csdnblog.net/gigix/archive/2004...
  • kingofark
  • kingofark
  • 2004-06-17 11:42:00
  • 3619

Spring原理-IoC容器初始化过程

IoC容器初始化过程 IoC容器的两个核心接口BeanFactory和ApplicationContext大概功能都讲解了一些,接下来我们讲解一下IoC容器的初始化过程,让大家有一个深一点的理解。讲...
  • hotdust
  • hotdust
  • 2016-11-07 22:46:03
  • 295

Spring IOC初始化过程

Spring IOC初始化过程——源码解读 Spring IOC的核心是BeanFactory 其实SpringIOC初始化的过程就是准备好BeanFactory的过程。 (1)定位并获取资源文件 C...
  • u010796790
  • u010796790
  • 2016-09-22 15:21:14
  • 1018

Spring 框架IOC的初始化过程

Spring 框架IOC的初始化过程1、Bean的初始化入口:2、Bean的初始化
  • dalinsi
  • dalinsi
  • 2016-11-01 20:04:43
  • 143

Spring中如何向 Bean注入系统属性或环境变量

在 Spring 中为 javabean 注入属性文件中的属性值一般人都知道的,可以通过 org.springframework.beans.factory.config.PropertyPlace...
  • kolabb
  • kolabb
  • 2015-08-18 14:26:13
  • 1444

web容器初始化最后阶段执行refresh()

web容器初始化最后阶段执行refresh()方法,单提出来分析下: refresh()方法主要为IoC容器Bean的生命周期管理提供条件,Spring IoC容器载入Bean定义资源文件从其子...
  • luman1991
  • luman1991
  • 2016-08-17 21:19:43
  • 548

源码解读(二): spring容器初始化的refresh操作

在上一篇文章 源码解读(一): spring在web容器中的初始化过程 中,我们了解了Spring容器的初始化整个过程,但是你看了之后可能会有疑问。既然到这个时候初始化都已经完成了,那么bean的初始...
  • gloomy_114
  • gloomy_114
  • 2017-04-20 18:33:45
  • 817

做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一

经过上面几节的简单介绍我们了解了spring的一些组件,现在我们来分析一下AbstractApplicationContext中的refresh()这个核心方法吧~ 用我们上一节的代码,debug...
  • linuu
  • linuu
  • 2016-03-12 14:21:38
  • 3191

做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析后记1

上次分析refresh这块spring IoC的时候,时间比较仓促,只是debug了部分源码,大家分析起来不是很好~ 今天我们还是先总结一下吧~ spring在实例化bean的时候,根据bea...
  • linuu
  • linuu
  • 2016-03-14 15:35:18
  • 1266

Spring源码解析之零 ------ 容器初始化过程(refresh()方法)概要

本篇主要讲解,容器初始化时候的refresh()方法里的,几个重要方法的基本作用。 首先来看一下refresh()方法。spring容器的启动,创建bean,bean的初始化等一系列过程都在这个ref...
  • weililansehudiefei
  • weililansehudiefei
  • 2017-07-03 13:43:41
  • 566
收藏助手
不良信息举报
您举报文章:Spring IOC refresh()方法——系统属性及环境变量的初始化以及验证
举报原因:
原因补充:

(最多只允许输入30个字)