问题描述
这份代码是我照着一个视频(Spring教程IDEA版)发现的一个错误。当我尝试将jdbc配置的四个参数放到properties文件中,使用动态注入的方式完成jdbc的配置时(也就是在代码中导入.properties文件,使用占位符提取文件里的driver,url,username,passward),发现连接数据库失败了。贴上代码
jdbcConfig配置类中
package config;
@Configuration
@PropertySource(value = {"classpath:config/jdbc.properties"})
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* @Description: 使用c3p0这个jar包中的ComboPooledDataSource 配置数据源 ,也就是配置driver,url,user,password这四个值
* 使用@Bean注解
* @Param:
* @return:
* @Author: svllen
* @Date: 2019/4/24
*/
@Bean(name = "dataSource")
public DataSource createDataSource() {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
} catch (Exception e) {
e.printStackTrace();
}
return dataSource;
}
/**
* @Description: 配置QueryRunner,并注入数据源。通过注解的方式
* @Param:
* @return:
* @Author: svllen
* @Date: 2019/4/24
*/
@Bean(name = "runner")
public QueryRunner createQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}
}
jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springDemoInXml?useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=12315
运行后报错:java.sql.SQLException: Connections could not be acquired from the underlying database!
其实这个报错就是报连接数据库失败
问题所在
我通过debug发现了一些端倪,案例来说通过@Value("${}")应该可以注入这几个值,但是debug发现这些值并没有注入,还是" ${jdbc.driver}"的这种形式。判断要么是jdbc.properties文件没导入成功,要么是 $占位符没起作用。最后确定了,是 $占位符的问题
解决方法
要想在Spring中使用$占位符,必须得在Spring容器中创建一个PropertySourcesPlaceholderConfigurer的Bean对象。
即在JdbcConfig使用@Bean注解创建PropertySourcesPlaceholderConfigurer的Bean对象。
@Configuration
@PropertySource(value = {"classpath:config/jdbc.properties"})
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//创建PropertySourcesPlaceholderConfigurer的Bean对象,有了它$占位符才起作用
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
//其他代码
}
这样就解决了