使用外部属性文件 
在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息 (例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean 配置相分离 Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器 , 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件 中. 可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量. Spring 还允许在属性文件中使用 ${propName},以实现属性之间的相互引用。
 
连数据库示例,本地要有数据库且开启。  新建个包,com.liudehua,新建个Main.java:1
2
3
4
5
6
7
public class Main {
	public static void main(String[] args) throws SQLException {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-properties.xml");
		DataSource dataSource = (DataSource)ctx.getBean("dataSource");
		System.out.println(dataSource.getConnection());
	}
}
新建个beans-properties.xml配置文件:1
2
3
4
5
6
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  	<property name="user" value="root"></property>
  	<property name="password" value="123456"></property>
  	<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  	<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
</bean>
注意:这里我又踩坑了。后台报异常Connections could not be acquired from the underlying database!,遂百度,得知可能是以下几点造成的: 
1.驱动配置有误:driver=com.mysql.jdbc.Driver 
2.数据库连接地址有误 
3.密码或帐号有误 
4.数据库未启动或无权访问  
5.项目未引入对应的驱动jar包mysql-connector-java-5.1.6-bin.jar 和c3p0-0.9.1.2.jar  
6.mysql root没有远程访问的权限,需要增加权限,增加权限的步骤如下:进入mysql数据库:grant all privileges on .  to ‘root’@’%’ identified by ‘root’ with grant option;flush privileges; 后来,我想可能是我参数写错了,仔细找,发现确实拼错了,改之启动还是一样的错,然后看看第4点,嗯,我电脑上没有数据库。。。 
 
 
没数据库没关系,可以装,后面的接着学。部署数据库连接的基本信息最好是拿出来,放到一个属性文件里面。  src下新建一个属性文件,db.properties:1
2
3
4
user=root
password=123456
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///test
注意:本地mysql必须有一个名为test的数据库 
 
接下来引用该属性文件。 修改beans-properties.xml代码:1
2
3
4
5
6
7
8
9
<!-- 导入属性文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <!-- 使用外部化属性文件的属性 -->
  	<property name="user" value="${user}"></property>
  	<property name="password" value="${password}"></property>
  	<property name="driverClass" value="${driverClass}"></property>
  	<property name="jdbcUrl" value="${jdbcUrl}"></property>
</bean>
Spring表达式语言:SpEL 
Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。 语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL SpEL 为 bean 的属性进行动态赋值提供了便利  通过 SpEL 可以实现:
通过 bean 的 id 对 bean 进行引用 
调用方法以及引用对象中的属性 
计算表达式的值 
正则表达式的匹配 
 
 
字面量的表示:
整数:<property name="count" value="#{5}"/> 
小数:<property name="frequency" value="#{89.7}"/> 
科学计数法:<property name="capacity" value="#{1e4}"/> 
String可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value="#{'Chuck'}"/> 或 <property name='name' value='#{"Chuck"}'/> 
Boolean:<property name="enabled" value="#{false}"/> 
 
引用 Bean、属性和方法  1.引用其他对象:1
2
<!-- 通过value属性和SpEL配置bean之间的关系 -->
<property name="prefix" value="#{prefixGenerator}"></property>
2.引用其他对象的属性:1
2
<!-- 通过value属性和SpEL配置suffix属性值为另一个bean的suffix的属性值 -->
<property name="suffix" value="#{sequenceGenerator2.suffix}"></property>
3.调用其他方法,还可以链式操作:1
2
3
4
<!-- 通过value属性和SpEL配置suffix属性值为另一个bean的方法的返回值 -->
<property name="suffix" value="#{sequenceGenerator2.toString}"></property>
<!-- 方法的连缀 -->
<property name="suffix" value="#{sequenceGenerator2.toString.toUpperCase()}" />
4.调用静态方法或静态属性:通过 T()  调用一个类的静态方法,它将返回一个 Class Object,然后再调用相应的方法或属性:1
<property name="initValue" value="#{T(java.lang.Math).PI}" />
SpEL支持的运算符号  1.算数运算符:+, -, *, /, %, ^:1
2
3
4
5
6
<property name="adjustedAmount" value="#{counter.total + 2}" />
<property name="adjustedAmount" value="#{counter.total - 2}" />
<property name="circumference" value="#{2 * T(java.lang.Math).PI * circle.radius}" />
<property name="average" value="#{counter.total / counter.count}" />
<property name="remainder" value="#{counter.total % counter.count}" />
<property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}" />
2.加号还可以用作字符串连接:1
<constructor-arg value="#{performer.firstname + ' ' + performer.lastname}"/>
3.比较运算符: <, >, ==, <=, >=, lt, gt, eq, le, ge1
<property name="equal" value="#{counter.total == 100}" />
4.逻辑运算符号: and, or, not, |1
2
3
<property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 10000}" />
<property name="outOfStock" value="#{!product.available}" />
<property name="outOfStock" value="#{not product.available}" />
5.if-else 运算符:?: (ternary), ?: (Elvis)1
<constructor-arg value="#{songSelector.selectSong()=='Jingle Bells' ? 'pinao':'Jingle Bells'}" />
6.if-else 的变体1
<constructor-arg value="#{kenny.song ?:'Greensleeves'}" />
7.正则表达式:matches1
<constructor-arg value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}" />