Spring使用外部属性文件遇到的问题
关键字: context:property-placeholder ,classpath ,JDBC。
1. context:property-placeholder飘红
今天没啥要做的工作,于是继续看Spring4。
今天看到的是Spring使用外部属性文件。这个在jeecg中很多地方都用到了,但是原理是怎样的一直不是很清楚。
我按照课件走的时候,context:property-placeholder飘红,报以下错误
the matching wildcard is strict, but no declaration can be found for element context:property-placeholder
而且下面的${user}等等,ctrl+鼠标左键 点不动,。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<!-- 导入属性文件-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
<property name="driverClass" value="${driverclass}"/>
<property name="jdbcUrl" value="${jdbcurl}"/>
</bean>
</beans>
百度说原因是context:property-placeholder用了两行,显然不是这个问题。
打开之前做过的项目,找到使用过该代码的地方,仔细比对,发现是引用的问题。
报错的这里用的是
xmlns:context="http://www.springframework.org/schema/util"
正确的应该是
xmlns:context="http://www.springframework.org/schema/context"
xmlns(XML Namespaces的缩写)是一个属性,是XML(标准通用标记语言的子集)命名空间。作用是赋予命名空间一个唯一的名称。
xmlns充当了一个识别的功能。比如有两个名字一样的xml文件,一个描述水果,一个描述桌子,这俩文件如果一起被引用,就会发生命名冲突。XML 解析器是无法确定如何处理这类冲突。
为了解决上述问题,xmlns就产生了。
这么改完之后,虽然不报错了,但是问题并未解决。无法读取dbconfig
报错如下:
Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 5 in XML document from class path resource [beans-properties.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 2; cvc-elt.1: 找不到元素 'beans' 的声明。
再一次搜索,也是博客园的资料。参考地址:https://www.cnblogs.com/ttflove/p/6351345.html
于是我添加了解析文件地址。
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
为防止版本不对,我去自己做的项目里偷的哈哈哈哈哈
2. 然后问题依旧出现。
这次是数据库的问题。
Could not load JDBC driver class [com.mysql.jdbc.Driver]
查阅得知此问题是没有导包,在pom下添加mysql-connector-java.jar即可
3.添加后依旧报错
异常错误:Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
报这个问题的原因是,版本太高。在pom中把版本弄到5.1就好了。我图方便随便弄了个8.0.
4.改成5.1.41后依旧报错
WARN: Establishing SSL connection without server's identity verification is not recommended.
长长的一大串我就截一句话。这个问题的解决方法是,在数据库后面加长长的一串。
jdbc:mysql:///test?useUnicode=true&characterEncoding=utf-8&useSSL=false
5.改正后依旧报错。
这次的报错,是距离成功最近的一步。我加了输出语句,却没打印,也没停止运行,就输出了一长串。
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hgfec3aaosqcvdmzp00b|2c039ac6, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hgfec3aaosqcvdmzp00b|2c039ac6, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql:///texet?useUnicode=true&characterEncoding=utf-8&useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
然后就没了。我有个坏习惯就是遇到错先停止运行。查了半小时,终于有一次我没有停止, 过了半分钟左右,
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'texet'
然后我终于知道,我数据库名字写错了。
6. 终于成功输出
这次课程视频长度只有八分钟,改BUG改了两个小时。同志仍需努力。
main.java
package com.atguigu.spring.beans.properties;
import com.atguigu.spring.beans.autowire.Address;
import com.atguigu.spring.beans.autowire.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
import java.sql.SQLException;
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());
System.out.println("111");
}
}
beans-properties.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 导入属性文件-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
<property name="driverClass" value="${driverClass}"/>
<property name="jdbcUrl" value="${jdbcurl}"/>
</bean>
</beans>
db.properties
user=root
password=root
driverClass=com.mysql.jdbc.Driver
jdbcurl=jdbc:mysql:///text?useUnicode=true&characterEncoding=utf-8&useSSL=false
输出结果: