[zhuanzail1、先停止mysql服务2、在mysql的目录下找到my.ini,在[mysqld]后面加上skip-grant-tables3、启动mysql服务,打开Command Line Client以空密码登录4、退出mysql,并
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'[解决 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 问题 2011-02-27 10:22:15| 分类: Database学习|字号 订阅 最近新装好
这一句是很重要的信息,很奇怪的是原本配置的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 配置文件目录
3.3怀疑spring加载属性文件的过程中,username没有加载成功;
1)尝试将username写死在xml配置中,即:
改为
结果问题解决,没有出现异常。
但是driver 、url 、password 仍然是采用${}的引用
2)尝试将username改为jdbc,username,即:
jdbc.properties中
username=root改为
jdbc.username=root
相应的将xml中
改为
仍然OK,没有出现异常。
所以确定是spring加载过程中出现的问题,导致username的值不对,又或者是关键字,百度了很多,没有找到解释,就放弃了,自己摸索下。
3.4为了弄清楚具体怎么回事,我debug找通过源码查看加载过程
感谢idea的IDE的强大功能,能够提示下载源码。
至于从哪里开始:可以再细看日志,其实是有提示:
五月 29, 2016 2:16:57 下午 org.springframework.context.support.PropertySourcesPlaceholderConfigurer loadProperties
信息: Loading properties file from class path resource [jdbc.properties]
直接搜索这个类
PropertySourcesPlaceholderConfigurer进去之后,发现有很多方法,我采取的比较蠢的方法,在有Property这个单词的方法中都打了个断点,
再次debug启动test,
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
this.propertySources.addLast(
new PropertySource(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
@Override
public String getProperty(String key) {
return this.source.getProperty(key);
}
}
);
}
try {
PropertySource> localPropertySource =
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
if (this.localOverride) {
this.propertySources.addFirst(localPropertySource);
}
else {
this.propertySources.addLast(localPropertySource);
}
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
this.appliedPropertySources = this.propertySources;
}
同时,自己查看变量的值,确定下来所有的配置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看之前提到的那个方法中的红色部分代码;
PropertySourcesPropertyResolver这个类中这个方法: T getProperty(String key, Class targetValueType, booleanresolveNestedPlaceholders)这个方法会遍历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框架不熟练,很容易出现各种各样的问题,我都会尽量靠自己去解决,同时分享出来,也希望有各位能够指出不足,提出更好的方法。
[sql:C:\>mysql -u root -p Enter password: ****** Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.1