在spring配置文件中,我们经常见到context:property-placeholder/context:component-scan/ 等常用但比较特殊的标签。有时候我们会有疑问,这些标签是如何被定义的,又是如何被解析的。下面我会通过跟踪spring源码的方式,分析其中的原理。由于本人时间有限,本文不是一次性完成,会随着我的学习进度更新,本文也作为我个人学习笔记使用。(本文是以spring4.1.3版本为例) ####1.占位符
<context:property-placeholder/>
1)用法
最常用的用法就是作为加载数据库连接配置文件(如:db.properties)的占位符。
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:resource/*.properties" />
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
2)原理解析
第一步:我们先找到spring定义property-placeholder元素的XSD文档。因为是context标签命名空间所以该元素定义肯定实在spring的context包中。如下图:
在此文档中我找到了property-placeholder标签的定义 (为了简洁,下面代码去掉了大部分注释)
<xsd:element name="property-placeholder">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates replacement of ${...} placeholders by registering a...]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="propertyPlaceholder">
<xsd:attribute name="system-properties-mode" default="ENVIRONMENT">
<xsd:annotation>
<xsd:documentation><![CDATA[Controls how to resolve placeholders against...]]>
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ENVIRONMENT"/>
<xsd:enumeration value="NEVER"/>
<xsd:enumeration value="FALLBACK"/>
<xsd:enumeration value="OVERRIDE"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
第二部:由上面XSD文件中可以看出properties文件最终都被封装成了org.springframework.context.support.PropertySourcesPlaceholderConfigurer返回。 下面我从ClassPathXmlApplicationContext类入手跟踪,跟踪到如下调用栈。