简体   繁体   English

Spring Boot的DataSource外部化配置不起作用

[英]Spring Boot externalised configuration for DataSource not working

I have an application - using Spring 4.3.6 and Spring Boot 1.4.4 - which will be exported as a JAR. 我有一个应用程序-使用Spring 4.3.6和Spring Boot 1.4.4-将被导出为JAR。 I want to connect to a remote Oracle database but I am having trouble externalising the configuration without breaking the application. 我想连接到远程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): 当尝试在我的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

I have tried to remove @ConfigurationProperties and change app.datasource to spring.datasource . 我试图删除@ConfigurationProperties并将app.datasource更改为spring.datasource I have also tried to use DataSourceBuilder.create().build() which returns javax.sql.DataSource but the same error is thrown in both cases. 我也尝试过使用DataSourceBuilder.create().build()返回javax.sql.DataSource但是在两种情况下都会引发相同的错误。

I'm doing something wrong. 我做错了。 What's the correct way to successfully externalise the configuration? 成功外部化配置的正确方法是什么?

Suppose you have two datasources for two different Oracle databases. 假设您有两个不同的Oracle数据库的两个数据源。 Then you have the following properties file: 然后,您具有以下属性文件:

/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.location as 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文件

There should be no need to create the DataSource yourself. 无需自己创建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.properties file: 在您的类路径和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 @Autowired your DataSource 之后,您应该可以@Autowired您的DataSource

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

You cannot override the predefined properties provided by spring boot. 您不能覆盖Spring Boot提供的预定义属性。

Just use the following properties in application.properties file. 只需在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 @ConfigurationProperties is used at class level and the prefix "app" not "app.datasource" 除此之外,在类级别使用@ConfigurationProperties进行澄清,并且前缀"app"而不是"app.datasource"

@ConfigurationProperties(prefix = "app")

Now you have a class named DbProperties and 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. 现在,实际的config / component类应该如下所示。

@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 datasource which is same as the second part of the key 实例变量名称是datasource ,它与键的第二部分相同
  2. datasource is a class level instance datasource是一个类级别的实例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM