数据源的 Spring Boot 外部化配置不起作用
Posted
技术标签:
【中文标题】数据源的 Spring Boot 外部化配置不起作用【英文标题】:Spring Boot externalised configuration for DataSource not working 【发布时间】:2017-02-10 09:11:22 【问题描述】:我有一个应用程序 - 使用 Spring 4.3.6 和 Spring Boot 1.4.4 - 将作为 JAR 导出。我想连接到远程 Oracle 数据库,但在不破坏应用程序的情况下将配置外部化时遇到了问题。
这是我目前的解决方法:
import org.apache.tomcat.jdbc.pool.DataSource;
@Bean
public DataSource dataSource()
DataSource dataSource = new DataSource();
dataSource.setUrl("jdbc:oracle:thin:@ip-address:port:orcl");
dataSource.setUsername("user");
dataSource.setPassword("password");
dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
return dataSource;
通过以上操作,我的应用程序能够连接到数据库并成功执行查询。但是,当我尝试将配置外部化如下:
@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource()
return new DataSource();
// application.properties
app.datasource.url=jdbc:oracle:thin:@ip-address:port:orcl
app.datasource.username=user
app.datasource.password=password
app.datasource.driver-class-name=oracle.jdbc.OracleDriver
尝试在我的 Spring Boot Controller 中执行 jdbcTemplate.update(query)
时会出现以下错误(请注意,没有外部化上述工作):
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: The url cannot be null
我已尝试删除 @ConfigurationProperties
并将 app.datasource
更改为 spring.datasource
。我也尝试使用返回javax.sql.DataSource
的DataSourceBuilder.create().build()
,但在两种情况下都会引发相同的错误。
我做错了什么。成功将配置外部化的正确方法是什么?
【问题讨论】:
为什么还要创建自己的DataSource
...
一开始我并没有创建自己的。我使用的是 hsqldb,但它没有访问 Oracle 数据库的权限。我问了一个问题,答案是改成ojdbc,所以我就这么做了。现在它找不到自动装配到 jdbctemplate 的 bean,所以我去阅读了 spring 参考(自从我开始研究这个以来第 n 次),我认为问题是 DataSource 不知何故不存在,所以我猜我在做什么可能算作一个自定义数据源,因此我为什么要创建一个。现在它不会使用 application.properties 设置自动配置自己...
hsqldb 不是甲骨文...所以显然这永远行不通。您需要正确的驱动程序,而这些都不需要手动配置。此外,异常状态(清楚地)表明数据源存在但无法建立连接,因此(可能)您的用户名/密码组合有问题。基本上你只需要删除你的配置,在你的application.properties
重启中用spring.
替换app.
并检查你的异常。
【参考方案1】:
假设您有两个数据源用于两个不同的 Oracle 数据库。然后你有以下属性文件:
/path/to/config/application.properties
oracle1.username=YourUser1
oracle1.password=YourPassword1
oracle1.url=jdbc:oracle:thin:@localhost:1521:XE
oracle2.username=YourUser2
oracle2.password=YourPassword2
oracle2.url=jdbc:oracle:thin:@192.168.0.3:1521:XE
然后在一个配置文件中:
import oracle.jdbc.pool.OracleDataSource;
@Configuration
public class DatasourcesConfig
@Autowired
private Environment env;
@Primary
@Bean(name = "dataSource1")
DataSource oracle1DataSource() throws SQLException
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(env.getProperty("oracle1.username"));
dataSource.setPassword(env.getProperty("oracle1.password"));
dataSource.setURL(env.getProperty("oracle1.url"));
return dataSource;
@Bean(name = "dataSource2")
DataSource oracle2DataSource() throws SQLException
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(env.getProperty("oracle2.username"));
dataSource.setPassword(env.getProperty("oracle2.password"));
dataSource.setURL(env.getProperty("oracle2.url"));
return dataSource;
如果你想在运行jar时指定你的application.properties文件的外部位置,那么将spring.config.location
设置为系统属性,你可以试试:
java -jar target/your-application-0.0.1.jar -Dspring.config.location=/path/to/config/
确保在构建 jar 时排除 application.properties 文件
【讨论】:
【参考方案2】:应该不需要创建DataSource
yourself。
确保你有
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
依赖于您的类路径和 oracle 驱动程序,并将以下属性放入您的 application.properties
文件中:
spring.datasource.url=jdbc:oracle:thin:@ip-address:port:orcl
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
之后你应该可以@Autowired
你的DataSource
有关更多信息,请查看: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database
【讨论】:
【参考方案3】:您不能覆盖 spring boot 提供的预定义属性。
只需在application.properties
文件中使用以下属性即可。
spring.datasource.url=jdbc:oracle:thin:@ip-address:port:orcl
spring.datasource.data-username=user
spring.datasource.data-password=password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
另见:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
除此之外,澄清@ConfigurationProperties
用于类级别,前缀"app"
不是"app.datasource"
@ConfigurationProperties(prefix = "app")
现在你有一个名为DbProperties
的类,该类的属性与application.properties
中键的最后一部分相同
public class DBProperties
private String url;
private String username;
private String password;
// setters and getters
现在实际的配置/组件类应该如下所示。
@Component
@ConfigurationProperties(prefix = "app")
public class MyComponent
DBProperties datasource = new DBProperties();
public DBProperties getDatasource()
return datasource;
public void setDatasource(DBProperties datasource)
this.datasource = datasource;
请注意
-
实例变量名称为
datasource
,与key的第二部分相同
datasource
是一个类级别的实例
【讨论】:
以上是关于数据源的 Spring Boot 外部化配置不起作用的主要内容,如果未能解决你的问题,请参考以下文章