Программно настроить DataSource в Spring Boot

С помощью 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

Как программно установить имя пользователя / пароль для источника данных?

У нас есть политика не хранить учетные данные в виде обычного текста, и я должен использовать конкретного поставщика учетных данных там, где я работаю.


person Marsellus Wallace    schedule 02.03.2015    source источник


Ответы (8)


Вы можете использовать DataSourceBuilder, если используете jdbc стартер. Кроме того, чтобы переопределить bean-компонент автоконфигурации по умолчанию, вам необходимо пометить свой bean-компонент как @Primary

В моем случае у меня есть свойства, начинающиеся с префикса datasource.postgres.

E.g

@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();
}
person Eddú Meléndez    schedule 03.03.2015
comment
@Primary не является обязательным, поскольку автоконфигурация создает bean-компонент DataSource только тогда, когда никакой другой bean-компонент не определен. - person dunni; 03.03.2015
comment
create (), вероятно, должен быть первым - person Marsellus Wallace; 14.03.2015
comment
Первичный не требуется. @Bean позволяет загрузке Spring для регистрации конфигурации. имя класса драйвера, URL, пользователь, пароль требуется - person Kishore Guruswamy; 16.06.2016
comment
Согласно JavaDoc @Primary Указывает, что bean-компоненту следует отдать предпочтение, когда несколько кандидатов квалифицируются для автоматического связывания однозначной зависимости. docs.spring.io/ весна / документы / текущий / javadoc-api / org / - person Andres Felipe; 30.05.2017
comment
Но как насчет набора spring.datasource.validation-query, spring.datasource.test-while-idle и spring.datasource.time-between-eviction-runs-millis - person zhuguowei; 27.06.2017
comment
У меня также есть тот же вопрос - как установить spring.datasource.validation-query в многопользовательском проекте, где мы создаем DataSource во время выполнения с помощью DataSourceBuilder.create (). - person Vijay Shegokar; 08.08.2017
comment
как сделать то же самое с разными источниками данных для junit / local server / dev server - person Kalpesh Soni; 28.03.2018
comment
Могу ли я комбинировать аннотацию @ConfigurationProperties с программными настройками в DataSourceBuilder ?. Я хочу настроить запуски тестирования при заимствовании и вытеснения, но в построителе нет возможности установить эти значения. - person dantebarba; 24.09.2018
comment
Кажется, это больше не работает, вам следует обновить свой ответ - person Madeo; 11.03.2021

Мой проект 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();
    }
}
person Alfer Wei    schedule 15.07.2016
comment
Этот ответ помогает, потому что он показывает, как использовать свойства spring.datasource по умолчанию для определения DataSource. Обратите внимание: если, скажем, вы хотите переопределить только пароль, вам нужно удалить определение пароля из application.properties (или application.yml) и установить это свойство в коде. - person ; 10.09.2017
comment
@Willie Wheeler Вы уверены, что это сработает? Поскольку, насколько я понимаю, приведенный выше код вернет совершенно новый компонент источника данных. Это означает, что свойства spring.datasource не вступят в силу и будут заменены новым компонентом. - person Fadhlie Ikram; 17.05.2018
comment
Да, я использовал этот подход для переноса паролей в Vault. - person ; 18.05.2018
comment
@WillieWheeler Вы правы. Я просто попробовал, и все работает. - person Fadhlie Ikram; 18.05.2018
comment
Приятно слышать @FadhlieIkram. Спасибо за проверку. - person ; 21.05.2018

Все, что вам нужно сделать, это аннотировать метод, который возвращает DataSource, с помощью @Bean. Полный рабочий пример приводится ниже.

@Bean
public DataSource dataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.url(dbUrl);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        return dataSourceBuilder.build();   
}
person Rodrigo Villalba Zayas    schedule 08.10.2015

Если вы используете последнюю версию Spring Boot (со стартером jdbc и 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();
}
person ACV    schedule 18.09.2018
comment
Мне также пришлось объявить bean-компонент DataSource как @Primary. - person Nis; 28.02.2019
comment
Есть более простой способ: в свойствах приложения (например, applicationaiotion.yml) переименовать: spring.datasource.url в spring.datasource.jdbc-url. Это должно помочь !!! (Так было в моем случае - SpringBoot v2.3.2) - person davide79; 19.08.2020

Если вам нужно больше конфигураций источника данных, например

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

person zhuguowei    schedule 24.07.2016

В качестве альтернативного способа вы можете использовать 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;
}

Однако будьте осторожны при его использовании, потому что:

ПРИМЕЧАНИЕ. Этот класс не является фактическим пулом соединений; на самом деле он не объединяет соединения. Он просто служит простой заменой полноценного пула соединений, реализуя тот же стандартный интерфейс, но создавая новые соединения при каждом вызове. справочник

person MMKarami    schedule 20.04.2018

для 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();
}
person Christian Altamirano Ayala    schedule 12.09.2019

Я настроил Tomcat DataSource в Spring-Boot 2.

Версии зависимости:

  • spring -boot: 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

Java

@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.

person Vladimir    schedule 22.11.2019