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

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

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出现。

阅读更多

没有更多推荐了,返回首页