Introduction
This tutorial will show you how you can get a list of data sources using Spring framework. I will define multiple datasources in Spring. There may be situations where you need to define multiple datasources in Spring application.
Why do you need multiple DataSource? You might need to connect to multiple different databases from your same application. Then you need to define multiple datasources to insert or update in different database servers.
Related Posts:
So in this case you can have different datasource bean ids configured in Spring configuration class and You can use those datasources as per your needs in the different part of the application when required.
Here I am going to create a datasource holder class which will give you a list of all datasources available in the entire application.
Prerequisites
Eclipse 2020-06, At least Java 8, Gradle 6.5.1, Maven 3.6.3, Spring 5.2.8
Project Setup
You can create either gradle or maven based project in Eclipse. The name of the project is spring-multiple-datasources.
I have added two different database types, such as, MySQL and PostgreSQL because you may need to work different databases.
if you are creating gradle based project then use below build.gradle script:
plugins {
id 'java-library'
}
repositories {
jcenter()
}
dependencies {
implementation 'org.springframework:spring-core:5.2.8.RELEASE'
implementation 'org.springframework:spring-context:5.2.8.RELEASE'
implementation 'org.springframework:spring-jdbc:5.2.8.RELEASE'
implementation 'mysql:mysql-connector-java:8.0.17'
implementation 'org.postgresql:postgresql:42.2.14'
implementation 'javax.annotation:javax.annotation-api:1.3.2'
//required for JDK 9 or above
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
}
If you are creating maven based project then you can use below pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.roytuts</groupId>
<artifactId>spring-multiple-datasources</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>at least 1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.14</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<!--required only if jdk 9 or higher version is used-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
DataSource Configuration
Now I am going to configure datasources. First you need to have the configuration file. The configuration file contains the database setting for different servers.
Create a file jdbc.properties under classpath folder src/main/resources with the following details.
jdbc.mysql.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://localhost:3306/roytuts
jdbc.mysql.username=root
jdbc.mysql.password=root
jdbc.postgresql.driverClassName=org.postgresql.Driver
jdbc.postgresql.url=jdbc:postgresql://localhost:5432/roytuts
jdbc.postgresql.username=root
jdbc.postgresql.password=root
Next I am going to create datsources bean and the bean for a class that finds all available datsources in the entire application.
package com.roytuts.spring.multiple.datasources.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import com.roytuts.spring.multiple.datasources.DataSources;
@Configuration
@PropertySource("classpath:jdbc.properties")
@ComponentScan(basePackages = "com.roytuts.spring.multiple.datasources.config")
public class Config {
@Autowired
private Environment environment;
@Bean
public DataSource dataSourceMysql() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.mysql.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.mysql.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.mysql.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.mysql.password"));
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplateMysql() throws ClassNotFoundException {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceMysql());
return jdbcTemplate;
}
@Bean
public DataSource dataSourcePostgresql() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.postgresql.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.postgresql.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.postgresql.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.postgresql.password"));
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplatePostgresql() throws ClassNotFoundException {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourcePostgresql());
return jdbcTemplate;
}
@Bean
public DataSources dataSources() {
return new DataSources();
}
}
The corresponding DataSources class is given below. Here I am using @PostConstruct
annotation to execute the method once constructor is loaded and finding all available datasources and storing into a Map object.
package com.roytuts.spring.multiple.datasources;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DataSources {
private Map<String, DataSource> dataSourceMap;
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void init() {
dataSourceMap = applicationContext.getBeansOfType(DataSource.class);
}
public Map<String, DataSource> getDataSources() {
return dataSourceMap;
}
}
Testing the Application
Next I am going to create a class having main method to load the required beans using ApplicationContext
.
package com.roytuts.spring.multiple.datasources;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.roytuts.spring.multiple.datasources.config.Config;
public class SpringMultipleDataSourcesApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
DataSources dataSources = context.getBean(DataSources.class);
dataSources.getDataSources().forEach((k, v) -> System.out.println("Key: " + k + ", Value: " + v));
((ConfigurableApplicationContext) context).close();
}
}
Executing the above code will give you the following output:
Key: dataSourceMysql, Value: org.springframework.jdbc.datasource.DriverManagerDataSource@6200f9cb
Key: dataSourcePostgresql, Value: org.springframework.jdbc.datasource.DriverManagerDataSource@2002fc1d
Source Code
Thanks for reading.