oracle 数据源的 Spring Boot 外部化配置不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42155491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:23:07  来源:igfitidea点击:

Spring Boot externalised configuration for DataSource not working

springoraclejdbcspring-bootspring-jdbc

提问by thegreatjedi

I have an application - using Spring 4.3.6 and Spring Boot 1.4.4 - which will be exported as a JAR. I want to connect to a remote Oracle database but I am having trouble externalising the configuration without breaking the application.

我有一个应用程序 - 使用 Spring 4.3.6 和 Spring Boot 1.4.4 - 它将作为 JAR 导出。我想连接到远程 Oracle 数据库,但在不破坏应用程序的情况下外部化配置时遇到了问题。

This is my current workaround:

这是我目前的解决方法:

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;
}

With the above, my application is able to connect to the database and execute queries successfully. However, when I try to externalise the configuration as follows:

通过以上操作,我的应用程序能够连接到数据库并成功执行查询。但是,当我尝试按如下方式外部化配置时:

@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

I will get the following error when trying to execute jdbcTemplate.update(query)in my Spring Boot Controller (note that without externalising the above works):

尝试jdbcTemplate.update(query)在我的 Spring Boot Controller 中执行时,我会收到以下错误(请注意,没有外部化上述工作):

org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: The url cannot be null

I have tried to remove @ConfigurationPropertiesand change app.datasourceto spring.datasource. I have also tried to use DataSourceBuilder.create().build()which returns javax.sql.DataSourcebut the same error is thrown in both cases.

我试图删除@ConfigurationProperties并更改app.datasourcespring.datasource. 我也尝试使用DataSourceBuilder.create().build()which 返回,javax.sql.DataSource但在两种情况下都会引发相同的错误。

I'm doing something wrong. What's the correct way to successfully externalise the configuration?

我做错了什么。成功外部化配置的正确方法是什么?

回答by Daniel Mora

Suppose you have two datasources for two different Oracle databases. Then you have the following properties file:

假设您有用于两个不同 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

Then in a configuration file:

然后在一个配置文件中:

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;
  }
}

If you want to specify the external location of your application.properties file when running the jar, then set the spring.config.locationas a system property, you can try:

如果您想在运行 jar 时指定 application.properties 文件的外部位置,则将其设置spring.config.location为系统属性,您可以尝试:

java -jar target/your-application-0.0.1.jar -Dspring.config.location=/path/to/config/

Make sure the application.properties file is excluded when building the jar

确保在构建 jar 时排除 application.properties 文件

回答by Markus Heider

There should be no need to create the DataSourceyourself.

应该没有必要创建DataSource自己。

Make sure you have the

确保你有

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
</dependency>

Dependecy in your classpath and the oracle driver and put following properties in your application.propertiesfile:

依赖于您的类路径和 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

After that you should be able to @Autowiredyour DataSource

在此之后,你应该能够@AutowiredDataSource

For more information have a look at: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database

有关更多信息,查看:https: //docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database

回答by Avinash

You cannot override the predefined properties provided by spring boot.

您不能覆盖 spring boot 提供的预定义属性。

Just use the following properties in application.propertiesfile.

只需在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

See Also : https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

另见:https: //docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

Apart from above, to clarify @ConfigurationPropertiesis used at class level and the prefix "app"not "app.datasource"

除上述之外,澄清@ConfigurationProperties是在类级别使用的,前缀"app"不是"app.datasource"

@ConfigurationProperties(prefix = "app")

Now you have a class named DbPropertiesand the properties of the class is same as the last part of the key in application.properties

现在你有一个名为的类,该类DbProperties的属性与键的最后一部分相同application.properties

public class DBProperties {
    private String url;
    private String username;
    private String password;
    // setters and getters
}

Now the actual config/component class should look like following.

现在实际的配置/组件类应该如下所示。

@Component
@ConfigurationProperties(prefix = "app")
public class MyComponent {
    DBProperties datasource = new DBProperties();

    public DBProperties getDatasource() {
        return datasource;
    }

    public void setDatasource(DBProperties datasource) {
        this.datasource = datasource;
    }    
}

Please note

请注意

  1. The instance variable name is datasourcewhich is same as the second part of the key
  2. datasourceis a class level instance
  1. 实例变量名称datasource与键的第二部分相同
  2. datasource是一个类级别的实例