在Spring Boot中以编程方式配置DataSource


74

使用Spring Boot,我可以JdbcTemplate使用以下实例化一个:

码:

@Autowired
private JdbcTemplate jdbcTemplate;

特性:

spring.datasource.url=jdbc:postgresql://my_url:my_port/my_other_stuff
spring.datasource.username=my_user_name
spring.datasource.password=my_password
spring.datasource.driver-class-name=org.postgresql.Driver

这将创建一个数据源类: org.apache.tomcat.jdbc.pool.DataSource

如何以编程方式设置DataSource用户名/密码?

我们有一项政策,不要以纯文本格式存储凭据,我必须在工作的地方使用特定的凭据提供程序。

Answers:


89

您可以使用DataSourceBuilder,如果你使用的是jdbc首发。另外,为了覆盖默认的自动配置Bean,您需要将Bean标记为@Primary

就我而言,我具有以datasource.postgresprefix开头的属性。

例如

@ConfigurationProperties(prefix = "datasource.postgres")
@Bean
@Primary
public DataSource dataSource() {
    return DataSourceBuilder
        .create()
        .build();
}

如果对您不可行,则可以使用

@Bean
@Primary
public DataSource dataSource() {
    return DataSourceBuilder
        .create()
        .username("")
        .password("")
        .url("")
        .driverClassName("")
        .build();
}

7
不需要@Primary,因为在未定义其他bean的情况下,AutoConfiguration仅创建一个DataSource bean。
dunni 2015年

create()应该应该是第一个
Marsellus Wallace 2015年

不需要主要的。@Bean使Spring Boot可以注册配置。需要驱动程序类名称,URL,用户,密码
Kishore Guruswamy

按照JavaDoc @Primary的指示,当多个候选者有资格自动装配单值依赖项时,应优先考虑Bean。docs.spring.io/spring/docs/current/javadoc-api/org/...
安德烈斯·费利佩·

6
但如何设置spring.datasource.validation-queryspring.datasource.test-while-idlespring.datasource.time-between-eviction-runs-millis
zhuguowei

26

我的spring-boot项目在您的协助下已正常运行。yaml数据源配置为:

spring:
  # (DataSourceAutoConfiguration & DataSourceProperties)
  datasource:
    name: ds-h2
    url: jdbc:h2:D:/work/workspace/fdata;DATABASE_TO_UPPER=false
    username: h2
    password: h2
    driver-class: org.h2.Driver

自定义数据源

@Configuration
@Component
public class DataSourceBean {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    @Primary
    public DataSource getDataSource() {
        return DataSourceBuilder
                .create()
//                .url("jdbc:h2:D:/work/workspace/fork/gs-serving-web-content/initial/data/fdata;DATABASE_TO_UPPER=false")
//                .username("h2")
//                .password("h2")
//                .driverClassName("org.h2.Driver")
                .build();
    }
}

3
这个答案很有帮助,因为它显示了如何使用默认的spring.datasource属性来定义DataSource。请注意,例如,如果您只想覆盖密码,则需要从application.properties(或application.yml)中删除密码定义,并在代码中设置该属性。

@Willie Wheeler您确定这行得通吗?因为据我所知,上面的代码将返回一个全新的数据源bean。意味着spring.datasource属性不会生效,并且将由新bean代替。
Fadhlie Ikram '18

1
是的,我已经使用这种方法将密码外部化到保险柜中。

1
@WillieWheeler你是对的。我只是尝试了,而且效果很好。
Fadhlie Ikram '18年

很高兴听到@FadhlieIkram。感谢您的检查。

15

您需要做的就是用@Bean注释一个返回DataSource的方法。下面是一个完整的工作示例。

@Bean
public DataSource dataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.url(dbUrl);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        return dataSourceBuilder.build();   
}

10

如果您使用的是最新的Spring Boot(带有jdbc starter和Hikari),则会遇到: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName. 解决此问题的方法:

  1. 在您的application.properties中:

datasource.oracle.url=youroracleurl

  1. 在您的应用程序中定义为bean(@Primary是必需的!):
@Bean
@Primary
@ConfigurationProperties("datasource.oracle")
public DataSourceProperties getDatasourceProperties() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("datasource.oracle")
public DataSource getDatasource() {
    return getDatasourceProperties().initializeDataSourceBuilder()
           .username("username")
           .password("password")
           .build();
}

我还必须将DataSource bean声明为@Primary。
尼斯

3
有一个更简单的方法:在应用程序属性(即applicaiotion.yml)中将:重命名spring.datasource.urlspring.datasource.jdbc-url。这应该可以解决问题!!!(在我的情况下确实如此
-SpringBoot

4

如果您想要更多的datesource配置,例如

spring.datasource.test-while-idle=true 
spring.datasource.time-between-eviction-runs-millis=30000
spring.datasource.validation-query=select 1

您可以使用以下代码

@Bean
public DataSource dataSource() {
    DataSource dataSource = new DataSource(); // org.apache.tomcat.jdbc.pool.DataSource;
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setTestWhileIdle(testWhileIdle);     
    dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMills);
    dataSource.setValidationQuery(validationQuery);
    return dataSource;
}

请参阅:Spring boot jdbc连接


2

作为替代方法,您可以使用DriverManagerDataSource,例如:

public DataSource getDataSource(DBInfo db) {

    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setUsername(db.getUsername());
    dataSource.setPassword(db.getPassword());
    dataSource.setUrl(db.getUrl());
    dataSource.setDriverClassName(db.getDriverClassName());

    return dataSource;
}

但是,请谨慎使用它,因为:

注意:此类不是实际的连接池;它实际上并不合并连接。它只是对成熟的连接池的简单替代,实现了相同的标准接口,但是在每个呼叫上都创建了新的Connections。参考


1
NOTE: Within special class loading environments such as OSGi, this class is effectively superseded by SimpleDriverDataSource due to general class loading issues with the JDBC DriverManager that be resolved through direct Driver usage (which is exactly what SimpleDriverDataSource does).
specializt

1

对于springboot 2.1.7,使用url似乎无法正常工作。改为使用jdbcUrl进行更改。

在属性中:

security:
      datasource:
        jdbcUrl: jdbc:mysql://ip:3306/security
        username: user
        password: pass

在Java中:

@ConfigurationProperties(prefix = "security.datasource")
@Bean("dataSource")
@Primary
public DataSource dataSource(){

    return DataSourceBuilder
            .create()
            .build();
}

0

我在Spring-Boot 2中自定义了Tomcat DataSource

依赖版本:

  • 春季引导:2.1.9.RELEASE
  • Tomcat的jdbc:9.0.20

可能对某人有用。

application.yml

spring:
    datasource:
        driver-class-name: org.postgresql.Driver
        type: org.apache.tomcat.jdbc.pool.DataSource
        url: jdbc:postgresql://${spring.datasource.database.host}:${spring.datasource.database.port}/${spring.datasource.database.name}
        database:
            host: localhost
            port: 5432
            name: rostelecom
        username: postgres
        password: postgres
        tomcat:
            validation-query: SELECT 1
            validation-interval: 30000           
            test-on-borrow: true
            remove-abandoned: true
            remove-abandoned-timeout: 480
            test-while-idle: true
            time-between-eviction-runs-millis: 60000
            log-validation-errors: true
            log-abandoned: true

爪哇

@Bean
@Primary
@ConfigurationProperties("spring.datasource.tomcat")
public PoolConfiguration postgresDataSourceProperties() {
    return new PoolProperties();
}

@Bean(name = "primaryDataSource")
@Primary
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource primaryDataSource() {
    PoolConfiguration properties = postgresDataSourceProperties();
    return new DataSource(properties);
}

这样做的主要原因是应用程序中有多个数据源,其中之一必须标记为@Primary

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.