Data Boot的Spring Boot外部化配置无法正常工作

时间:2017-02-10 09:11:23

标签: spring oracle jdbc spring-boot spring-jdbc

我有一个应用程序 - 使用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。我还尝试使用返回DataSourceBuilder.create().build()的{​​{1}},但在这两种情况下都会抛出相同的错误。

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

3 个答案:

答案 0 :(得分: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文件

答案 1 :(得分:0)

不需要自己创建DataSource

确保您拥有

<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

答案 2 :(得分:0)

您无法覆盖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;
    }    
}

请注意

  1. 实例变量名称为datasource,与密钥的第二部分
  2. 相同
  3. datasource是一个班级实例