ssm整合过程中问题记录--异常:Access denied for user 'Administrator'@'localhost' (using password: YES)...

1、操作过程:

spring整合mybatis+mysql,所有配置与代码都以完成,进行junit单元测试的。

2、异常现象:

启动junit测试接口方法,出现以下异常:

 

 

警告: com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@4c9258a6 -- Acquisition Attempt Failed!!! 

Clearing pending acquires. While trying to acquire a needed new resource, 

we failed to succeed more than the maximum number of allowed acquisition attempts (2). Last acquisition attempt exception: 

java.sql.SQLException: Access denied for user 'Administrator'@'localhost' (using password: YES)

 

3、分析步骤:

3.1解析错误信息:

 Access denied for user 'Administrator'@'localhost'

这一句是很重要的信息,很奇怪的是原本配置的root用户,结果错误日志显示的是Administrator。

 

3.2检查配置,并没有什么问题。

 

配置的jdbc如下:

 

 

jdbc.properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/seckill?useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
    
 

spring-dao.xml 配置文件目录

 

[html] view plain copy

 

  1. <!--2、数据库连接池-->  
  2. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
  3. <!--配置连接池属性-->  
  4. <property name="driverClass" value="${driver}"/>  
  5. <property name="jdbcUrl" value="${url}"/>  
  6. <property name="user" value="${username}"/>  
  7. <property name="password" value="${password}"/>  
  8.   
  9. <!--c3p0连接池私有属性-->  
  10. <property name="maxPoolSize" value="30"/>  
  11. <property name="minPoolSize" value="10"/>  
  12. <property name="autoCommitOnClose" value="false"/>  
  13. <!--获取链接超时时间-->  
  14. <property name="checkoutTimeout" value="1000"/>  
  15. <!--重试次数-->  
  16. <property name="acquireRetryAttempts" value="2"/>  
  17. </bean>  

 

3.3怀疑spring加载属性文件的过程中,username没有加载成功;

 

1)尝试将username写死在xml配置中,即:

[html] view plain copy

 

  1. <property name="user" value="${username}"/>  

改为

[html] view plain copy

 

  1. <property name="user" value="root"/>  

[html] view plain copy

 

  1. 结果问题解决,没有出现异常。  

[html] view plain copy

 

  1. 但是driver 、url 、password 仍然是采用${}的引用  

[html] view plain copy

 

  1. </pre><pre name="code" class="html">2)尝试将username改为jdbc,username,即:  

[html] view plain copy

 

  1. jdbc.properties中  

[html] view plain copy

 

  1. username=root  

改为

[html] view plain copy

  1. jdbc.username=root  

相应的将xml中

 

[html] view plain copy

  1. <property name="user" value="${username}"/>  

改为

 

[html] view plain copy

  1. <pre name="code" class="html"><property name="user" value="${jdbc.username}"/>  

[html] view plain copy

  1. 仍然OK,没有出现异常。  

 

 

[html] view plain copy

  1. <pre name="code" class="html"><span style="color:#cc0000;"><strong>所以确定是spring加载过程中出现的问题</strong></span>,导致username的值不对,又或者是关键字,百度了很多,没有找到解释,就放弃了,自己摸索下。  
 

[html] view plain copy

  1. </pre><pre name="code" class="html">3.4为了弄清楚具体怎么回事,我debug找通过源码查看加载过程  

[html] view plain copy

  1. </pre><pre name="code" class="html"><span style="color:#009900;"><strong>感谢idea的IDE的强大功能,能够提示下载源码。</strong></span>  

[html] view plain copy

  1. <span style="color:#009900;"><strong>  
  2. </strong></span>  

[html] view plain copy

  1. 至于从哪里开始:可以再细看日志,其实是有提示:  

[html] view plain copy

  1. 五月 29, 2016 2:16:57 下午 org.springframework.context.support.<strong>PropertySourcesPlaceholderConfigurer</strong> loadProperties  
  2. 信息: Loading properties file from class path resource [jdbc.properties]  

[html] view plain copy

  1. </pre><pre name="code" class="html">直接搜索这个类<pre name="code" class="html"><strong>PropertySourcesPlaceholderConfigurer</strong>进去之后,发现有很多方法,我采取的比较蠢的方法,在有Property这个单词的方法中都打了个断点,  

[html] view plain copy

  1. 再次debug启动test,   

[html] view plain copy

  1. <pre style="widows: auto;"><pre name="code" class="java" style="font-family: 宋体; font-size: 10.5pt; line-height: 21px; background-color: rgb(255, 255, 255);">@Override  
  2. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  
  3.    if (this.propertySources == null) {  
  4.       this.propertySources = new MutablePropertySources();  
  5.       if (this.environment != null) {  
  6.          this.propertySources.addLast(  
  7.             new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {  
  8.                @Override  
  9.                public String getProperty(String key) {  
  10.                   return this.source.getProperty(key);  
  11.                }  
  12.             }  
  13.          );  
  14.       }  
  15.       try {  
  16.          PropertySource<?> localPropertySource =  
  17.                new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());  
  18.          if (this.localOverride) {  
  19.             this.propertySources.addFirst(localPropertySource);  
  20.          }  
  21.          else {  
  22.             this.propertySources.addLast(localPropertySource);  
  23.          }  
  24.       }  
  25.       catch (IOException ex) {  
  26.          throw new BeanInitializationException("Could not load properties", ex);  
  27.       }  
  28.    }  
  29.   
  30.    processProperties(beanFactory, <span style="color:#cc0000;">new PropertySourcesPropertyResolver(this.propertySources));</span>  
  31.    this.appliedPropertySources = this.propertySources;  
  32. }  
同时,自己查看变量的值,确定下来所有的配置properties都在 this.propertySources
 
其中包含2部分:环境变量和本地变量
 
 
 
 
 

 
 

this.propertiesSources

--propertyList

--0 [name='environmentProperties']

--source

--propertySources

--1[name='systemEnvironment']

--source

在这个属性下面发现了同为username=Administrator的环境变量;

 
在localProperty下的username=root
 
两者都是同一个key;
 
进一步,探究怎么会取的Administrator 而不是 root 继续 debug看之前提到的那个方法中的红色部分代码;
 

[java] view plain copy

 

  1. PropertySourcesPropertyResolver这个类中这个方法:  
<T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders)
这个方法会遍历this.propertySources这个对象,当找到了username之后就直接返回了,而按照解析的步骤,先解析的environmentProperty的属性,所以就将username赋值为了
username=Administrator 而不会去解析localProperty中的username。
 
 
 
3.5 解决方法:
分析了那么多最终是要解决的;
推荐的方法就是,避免取名与环境变量一致,如果保证不一致,那就写复杂点吧。
所以一般下面这种写法也就够了,这也是为什么网上很多都采用这种写法,今天算是明白的不这么写的隐患了。
 
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/seckill?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=123456
 
 
	
 
总结:问题来了,能够自己解决确实学到的非常多,由于使用ssm框架不熟练,很容易出现各种各样的问题,我都会尽量靠自己去解决,同时分享出来,
	也希望有各位能够指出不足,提出更好的方法。

转载于:https://my.oschina.net/ldm95/blog/883783

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值