今天就想研究研究底层的东西,说是底层其实也是基础,很多程序员(特指我)都会用却说不清原理,认真思考时会感到疑惑。那不说废话,先讲一下疑惑的点,为什么前端(freemarker)和后端(Spring的applicationContext.xml文件) 都在使用${}标签?
freemarker文件中:
<input name="myName" id="myName" value="${myName}"/>
applicationContext.xml文件中:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="${supermt4.jdbc.url}"></property>
<property name="user" value="${supermt4.jdbc.username}"></property>
<property name="password" value="${supermt4.jdbc.password}"></property>
<property name="maxIdleTime" value="300"></property> <!-- seconds -->
<property name="idleConnectionTestPeriod" value="3000"></property> <!-- seconds -->
<property name="testConnectionOnCheckout" value="true"/>
<property name="preferredTestQuery" value="select 1" />
</bean>
JAVA开发中大家第一反应肯定会想到EL表达式,它们是使用的EL表达式吗?我们来看下EL表达式的百科定义:
划重点,EL表达式是给JSP用的,换句话说在JSP中的才叫EL表达式,说明不仅xml文件中的不是EL,freemarker中的也不是。
那Freemarker是什么呢?查查资料就知道${}是属于ftl自己的语言,只要看一下Freemarker的文档就知道了,之前使用中拿来即用,没查没看没思考所以没认真区分。
那后端的是什么呢?直接说结论,是org.springframework.beans.factory.config.PropertyPlaceholderConfigurer这个类对properties文件特定写法的解析。
我们一步一步来看找打解析位置,首先找到引入xml文件中引入.properties的位置
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:test.properties</value>
</list>
</property>
</bean>
找到PropertyPlaceholderConfigurer的源码,找到processProperties方法
/**
* Visit each bean definition in the given bean factory and attempt to replace ${...} property
* placeholders with values from the given properties.
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
this.doProcessProperties(beanFactoryToProcess, valueResolver);
}
通过注释看到它是处理${}表达式的,它new了一个PlaceholderResolvingStringValueResolver对象,在它的构造方法中
public PlaceholderResolvingStringValueResolver(Properties props) {
this.helper = new PropertyPlaceholderHelper(
placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
this.resolver = new PropertyPlaceholderConfigurerResolver(props);
}
new了一个PropertyPlaceholderHelper对象,这个是后续的处理我们不看了,有需要可自己阅读源码。注意placeholderPrefix和placeholderSuffix的变量,我们找到它的定义
这就是我们项目中用到的${}表达式,明确了在xml中是
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer类中定义的使用方式,与EL表达式,与前端都没有关系。
今天终于不是云里雾里,搞的很清楚啦。有不明白的小伙伴也建议多看看源码哈。