在写SSM项目的时候,遇到错误信息如下:
create connection SQLException,url:jdbc:mysql://localhost:3306/test, errorCode 1045, state 28000
java.sql.SQLException: Access denied for user 'Zero'@'localhost' (using password: YES)
由errorCode 1045,state 28000
可知是授权问题或者密码错误,又因为password:YES
可知密码正确。然后我注意到用户名为Zero
,可我的jdbc.properties是这样的:
url:jdbc:mysql://localhost:3306/test
driverClassName:com.mysql.jdbc.Driver
username:root
password:1234
可以发现用户名在properties中写的是root而实际运行时却是Zero,经多方查阅后发现问题出在Spring的XML中配置导入properties文件时,具体代码如下:
<context:property-placeholder location="classpath:jdbc.properties" />
是不是觉得这句话没有问题?是的,这句话本身没有错误,有的项目中这样使用是没有影响的,问题出在这个标签有个属性system-properties-mode
而默认值为ENVIRONMENT,意思是在解析${username}这种占位符时,会先在当前系统环境中查找,其次才在配置的本地properties内寻找。又由于properties内username和系统环境的username重名所以才出现了如上的错误。
知道了原因,解决办法有两个:
1. 修改properties,在key值前加上前缀”jdbc.”
2. 设置<context:property-placeholder>
的属性system-properties-mode="FALLBACK"
,意思是先找本地properties后找系统环境。
修改后的jdbc.properties文件:
jdbc.url:jdbc:mysql://localhost:3306/test
jdbc.driverClassName:com.mysql.jdbc.Driver
jdbc.username:root
jdbc.password:1234
修改后的spring配置:
<context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="FALLBACK"/>
<context:property-placeholder>属性详解
location="属性文件,多个之间逗号分隔,或者可以使用通配符"
file-encoding="文件编码"
ignore-resource-not-found="是否忽略找不到的属性文件,如果不忽略,找不到将抛出异常"
ignore-unresolvable="是否忽略解析不到的属性,如果不忽略,找不到将抛出异常."
properties-ref="Spring内部Properties对象的Bean名" ,例如XML中配置的java.util.Properties对象
local-override="是否本地覆盖模式,即如果true,那么properties-ref的属性将覆盖location加载的属性,否则相反"
system-properties-mode="系统属性模式"
- ENVIRONMENT(默认):通过当前环境和本地properties解析占位符
- NEVER:只通过本地properties,不通过系统环境参数
- OVERRIDE:先系统环境参数后本地properties
- FALLBACK:先本地properties后系统环境参数
order="顺序" 多个该标签配置之间的检索顺序
配置多个<context:property-placeholder>
的方法
由于一般配置多个只会有一个生效,除了在一个里配置多个properties文件之外,就需要做如下配置:
<context:property-placeholder location="classpath:config.properties" ignore-unresolvable="true" order="1" />
<context:property-placeholder location="classpath:config2.properties" ignore-unresolvable="false" order="2" />
- order属性决定多个配置时的加载先后顺序,数字越小越先加载
- 当spring加载的
<context:property-placeholder>
的ignore-unresolvable属性为false,则停止扫描剩余的<context:property-placeholder>
,反之,则继续扫描. - 由于ignore-unresolvable=”true”时会忽略解析不到的属性,无法报错,所以我们需要在最后加载的
<context:property-placeholder>
的ignore-unresolvable属性设为false。
注意:多个配置文件中如果有属性名相同的情况,则后加载的会覆盖先加载的。
PS:PropertyPlaceholderConfigurer
和<context:property-placeholder>
是等效的,以上的规则对其也适用,有时错误产生的原因就在PropertyPlaceholderConfigurer
的配置上.
参考:
1. 如何定义多个context:property-placeholder配置?
2. Spring(13)——PropertyPlaceholderConfigurer(二)之namespace