zoukankan      html  css  js  c++  java
  • 环境准备

    前言

    环境准备是ApplicationContext扩展功能refresh函数中的第一个步骤,接下来我们就详细的看看准备了什么?

    环境准备

    prepareRefresh函数主要是做些准备工作,例如对系统属性及环境变量的初始化及验证。

    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();
    
            // Allow for the collection of early ApplicationEvents,
            // to be published once the multicaster is available...
            this.earlyApplicationEvents = new LinkedHashSet<>();
        }

     最后的两句代码才是关键,代码中没有什么逻辑处理,initPropertySources是空方法,专门留给子类去实现扩展功能的,没有任何的逻辑。而getEnvironment().validateRequiredProperties也因为没有需要验证的属性而没有做任何处理,那这些函数有什么用呢?Spring中存在相信就一定有它的作用,我们先来探索下各个函数的作用。

    (1)initPropertySources正符合Spring的开放式结构设计,给用户最大扩展Spring的能力。用户可以根据自身的需求重写initPropertySources方法,并在方法中进行个性化的属性处理及设置。

    (2)validateRequiredProperties则是对属性进行验证,那么如何验证呢?举个小例子来帮助理解:

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

    public class MyClassPathApplicationContext extends ClassPathXmlApplicationContext {
    
        public MyClassPathApplicationContext(String... configLocation){
            super(configLocation);
        }
    
        @Override
        protected void initPropertySources() {
            //添加验证要求
            getEnvironment().setRequiredProperties("VAR");
        }
    }

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

    public static void main(String[] args){
            ApplicationContext ac = new MyClassPathApplicationContext("spring-config.xml");
            User user = (User) ac.getBean("user");
            System.out.println(user.getName());
        }

    如果环境中没有配置VAR变量,运行上述测试代码:

    12月 28, 2018 9:38:07 下午 com.joe.applicant.MyClassPathApplicationContext prepareRefresh
    信息: Refreshing com.joe.applicant.MyClassPathApplicationContext@5b87ed94: startup date [Fri Dec 28 21:38:07 CST 2018]; root of context hierarchy
    Exception in thread "main" org.springframework.core.env.MissingRequiredPropertiesException: The following properties were declared as required but could not be resolved: [VAR]
        at org.springframework.core.env.AbstractPropertyResolver.validateRequiredProperties(AbstractPropertyResolver.java:140)
        at org.springframework.core.env.AbstractEnvironment.validateRequiredProperties(AbstractEnvironment.java:512)
        at org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:591)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:512)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
        at com.joe.applicant.MyClassPathApplicationContext.<init>(MyClassPathApplicationContext.java:10)
        at com.joe.applicant.MyClassPathApplicationContext.main(MyClassPathApplicationContext.java:21)

    发现报错,提示环境中没有VAR变量。

    设置环境变量:因为LZ使用的是IDEA,所以这里先展示如何设置环境变量:

    第一步:点击 Run ------->  Edit Configurations

    第二步:点击 需要运行的类,在Environment variables 点击设置变量

     

    第三步:设置对应变量

    保存后。在运行上述测试代码:

    十二月 29, 2018 10:40:21 上午 com.joe.mytag.application.MyClassPathApplicationContext prepareRefresh
    信息: Refreshing com.joe.mytag.application.MyClassPathApplicationContext@5910e440: startup date [Sat Dec 29 10:40:21 CST 2018]; root of context hierarchy
    十二月 29, 2018 10:40:21 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [spring.xml]
    Joe

    发现没有报错,成功运行。 

    参考:《Spring源码深度解析》 郝佳 编著:

    作者:Joe
    努力了的才叫梦想,不努力的就是空想,努力并且坚持下去,毕竟这是我相信的力量
  • 相关阅读:
    day04
    day02
    day01
    ORM + 单例
    ORM框架SQLAlchemy
    存储引擎 , 索引 ,慢日志查询 , explain查询优化, 权限管理
    事务,视图 ,函数,存储过程,触发器
    pymysql 操作 , sql注入
    外键,高级操作
    mysql 基本操作
  • 原文地址:https://www.cnblogs.com/Joe-Go/p/10193077.html
Copyright © 2011-2022 走看看