Spring boot: YAML multiple datasources
This post is an update from the original post created the 22nd of Nov 2015.
In this example we will see how to config two datasources on different environments (development, test, production) using a YAML config file. Before starting, I added in my pom.xml the spring-boot-starter-jdbc.
application.yml
In order to represent the several environments I used profiles. After that, for each environment I set the properties concerning the datasources. We can notice the two datasources each time.
Profiles are used to group beans together. For a specific profile the beans are created only if the profile is activated.
spring:
profiles.active: development
---
spring:
profiles: development
datasource:
db-person:
url: jdbc:oracle:thin:@db_person_dev
username: username
password: pwd
driver-class-name: oracle.jdbc.OracleDriver
test-on-borrow: true
validation-query: SELECT 1 FROM dual
db-contract:
url: jdbc:oracle:thin:@db_contract_dev
username: username
password: pwd
driver-class-name: oracle.jdbc.OracleDriver
test-on-borrow: true
validation-query: SELECT 1 FROM dual
---
spring:
profiles: test
datasource:
db-person:
url: jdbc:oracle:thin:@db_person_test
username: username
password: pwd
driver-class-name: oracle.jdbc.OracleDriver
test-on-borrow: true
validation-query: SELECT 1 FROM dual
db-contract:
url: jdbc:oracle:thin:@db_contract_test
username: username
password: pwd
driver-class-name: oracle.jdbc.OracleDriver
test-on-borrow: true
validation-query: SELECT 1 FROM dual
---
spring:
profiles: production
datasource:
db-person:
url: jdbc:oracle:thin:@db_person_prod
username: username
password: pwd
driver-class-name: oracle.jdbc.OracleDriver
test-on-borrow: true
validation-query: SELECT 1 FROM dual
db-contract:
url: jdbc:oracle:thin:@db_contract_prod
username: username
password: pwd
driver-class-name: oracle.jdbc.OracleDriver
test-on-borrow: true
validation-query: SELECT 1 FROM dual
---
Application.groovy
Usually, Spring boot creates automatically a datasource and a jdbcTemplate when the jdbc-starter is part of the dependencies. Behind the scene, it checks in classpath for libraries brought by the starters, based on the presence of certain libraries it will autoconfigure beans. Spring boot is said as opinionated. Also, it is worth mentioning that Spring Boot reads the application properties to auto-configure the beans. This is how Spring Boot can create a datasource, but you have to respect the right names for the properties.
In the case of multiple datasources Spring Boot can’t guess that you actually want multiple datasources. Hopefully, it’s possible to override Spring Boot behaviour and define these beans ourself.
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
import javax.sql.DataSource
@SpringBootApplication
class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
@ConfigurationProperties(prefix="datasource.db-person")
public DataSource personDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix="datasource.db-contract")
public DataSource contractDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public JdbcTemplate personJdbcTemplate(){
return new JdbcTemplate(personDataSource());
}
@Bean
public JdbcTemplate contractJdbcTemplate(){
return new JdbcTemplate(contractDataSource());
}
@Beans
public PersonRepository jdbcPersonRepository() {
PersonRepository personRepo = new JdbcPersonRepository();
personRepo.setJdbcTemplate(personJdbcTemplate());
return personRepo;
}
@Beans
public ContractRepository jdbcContractRepository() {
ContractRepository contractRepo = new JdbcContractRepository();
contractRepo.setJdbcTemplate(contractJdbcTemplate());
return contractRepo;
}
}