Spring3.1.0实现原理分析(三).配置数据

      今天我想谈一下,Spring从哪里获取配置数据? 配置数据做什么用处? 如何存储和访问配置数据?就像一辆汽车,开之前总得先加油吧,不然何如工作呢。


1.  配置数据有哪些,何时加载,其作用是什么。

       我觉得Spring的数据源至少可分为两类,JDK系统数据和用户配置数据。jdk系统数据具体是指System#getProperties()方法返回值和System#getenv()方法返回值。用户配置数据其一是使用<context:property-placeholder location="..." />指定的资源文件,最常见的场景就是在这个资源文件中配置数据库的用户名、密码等。用户配置数据还包括定义bean的资源文件,在Spring的初始化过程中会解析资源文件获取Bean定义对象注册到Bean工厂中。

       JDK系统配置数据是先于用户配置数据加载的,在ApplicationContext的构造函数中即被加载,如此早加载是因为可用它来解析用户指定的资源文件路径中可能存在的占位符。Bean定义资源文件而后加载,最后在容器后处理器中加载<context:property-placeholder location=""/>指定的资源文件,然后使用它来解析Bean定义中的占位符,比如你可能在Bean定义中使用${jdcb.uername}这个表达式代表数据库用户名。也就是说在实例化Bean对象前,Bean定义中的占位符已经被替换成实际值,但是Bean定义中的Spel表达式尚未被解析。


2.  如何加载、存储和访问JDK系统配置数据

       Spring所有的一切是从创建ApplicationContext(以下简称AC)开始的,而AC的构造函数中第一个步骤是创建“基于路径匹配的资源模式解析器”,这个类的作用是加载资源文件;第二个步骤就是创建“标准环境对象”。   

       在标准环境对象的构造函数中,它会调用JDK系统方法System#getProperties()和System#getenv(),两者的返回值分别是“Properties”和“ Map<String,String>”,是两种不同类型的对象。为了使用统一的方式访问它们,Spring会把它们包装成属性源对象(PropertySource),然后添加到自身持有的属性源集对象(PropertySources)中,再通过属性解析器对象(PropertyResolver)访问属性源对象。三者之间的关系可以用下图来表述,

  

       标准环境对象还有几个派生类,如标准Servlet环境对象(StandardServletEnvironment),这个类在超类把System#getProperties()和System#getenv()转换成属性源对象的基础上,还会把ServletConfig#servletConfigInitParams()和servletConfig#servletContextInitParams()包装成属性源对象。这里有个很有意思的处理方式,标准Servlet环境对象并没有获取真正的servletConfigInitParams和servletContextInitParams,仅仅只是两个存根属性源对象,然后由抽象可刷新Web容器把存根替换成真实对象,大概是为了避免标准Servlet环境对象对Web对象有依赖


3.  如何加载用户配置数据

     如果用户在Spring配置文件中使用<context:property-placeholder location="..." />指定了资源文件路径的话,Spring会自动注册一个容器后处理器,在3.1版本中这个类是“PropertySourcesPlaceholderConfigurer”,该对象持有标准环境对象,处理具体步骤如下:

a. 首先加载用户配置的资源文件,通过资源加载器(ResourceLoader)实现该功能,上面也说到过,AC构造函数函数中的第一步就是创建资源加载器, 通过它把资源文件转换成资源对象(Resource),然后把资源对象转换成属性集对象(java系统类),再把属性集合对象包装成属性源对象(PropertySource)

b. 合并标准环境对象的属性源对象和用户配置数据的属性源对象,默认用户配置属性源对象优先级高。

c. 创建解析器,解析bean定义中的占位符。 


好了,先写到这里。之所以讨论配置数据,是因为想搞清楚驱动Spring工作的能源是从哪来的,分别是哪些能源。

总结,能源有两部分,一部分是系统环境的,一部分是用户配置的,Spring会把所有的能源包装成属性源对象,然后通过属性解析器获取其中数据。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章