我开发了一个多租户spring boot应用程序,其中的数据源通过存储在application.properties中的数据库凭证进行初始化,如下所示:
application.properties
spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource2.url=jdbc:mysql://localhost:3306/db2
spring.multitenancy.datasource2.username=root
spring.multitenancy.datasource2.password=****
spring.multitenancy.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource3.url=jdbc:mysql://localhost:3306/db3
spring.multitenancy.datasource3.username=root
spring.multitenancy.datasource3.password=****
spring.multitenancy.datasource3.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=updateDataSourceConfig.java
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Bean(name = { "dataSource", "dataSource1" })
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
public DataSource dataSource1() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource1().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource1().getDriverClassName())
.username(this.multitenancyProperties.getDatasource1().getUsername())
.password(this.multitenancyProperties.getDatasource1().getPassword())
.url(this.multitenancyProperties.getDatasource1().getUrl());
return factory.build();
}
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource2")
public DataSource dataSource2() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource2().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource2().getDriverClassName())
.username(this.multitenancyProperties.getDatasource2().getUsername())
.password(this.multitenancyProperties.getDatasource2().getPassword())
.url(this.multitenancyProperties.getDatasource2().getUrl());
return factory.build();
}
@Bean(name = "dataSource3")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource3")
public DataSource dataSource3() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource3().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource3().getDriverClassName())
.username(this.multitenancyProperties.getDatasource3().getUsername())
.password(this.multitenancyProperties.getDatasource3().getPassword())
.url(this.multitenancyProperties.getDatasource3().getUrl());
return factory.build();
}
}在这里,数据源通过存储在应用程序属性中的值进行初始化。
MultitenancyProperties.java
@ConfigurationProperties("spring.multitenancy")
public class MultitenancyProperties {
@NestedConfigurationProperty
private DataSourceProperties datasource1;
@NestedConfigurationProperty
private DataSourceProperties datasource2;
@NestedConfigurationProperty
private DataSourceProperties datasource3;
public DataSourceProperties getDatasource1() {
return datasource1;
}
public void setDatasource1(DataSourceProperties datasource1) {
this.datasource1 = datasource1;
}
public DataSourceProperties getDatasource2() {
return datasource2;
}
public void setDatasource2(DataSourceProperties datasource2) {
this.datasource2 = datasource2;
}
public DataSourceProperties getDatasource3() {
return datasource3;
}
public void setDatasource3(DataSourceProperties datasource3) {
this.datasource3 = datasource3;
}
}Spring boot应用程序启动器
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(MultitenancyProperties.class)
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}如何通过读取存储在主数据源的表中的数据库凭据以编程方式读取application.properties和其他数据源(dataSource2、dataSource3),从而仅初始化主数据源。
发布于 2017-04-07 05:00:07
假设您的原始数据源中有一个名为DATABASECONFIG的DB,模式如下:
+-----------+-----------+-----------+-----------+-----------+
| DATABASECONFIG |
+-----------+-----------+-----------+-----------+-----------+
| DB_NAME | URL | USERNAME | PASSWORD | DRIVER |
+-----------+-----------+-----------+-----------+-----------+您可以将DataSourceConfig类更改为如下所示:
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Bean(name = { "dataSource", "dataSource1" })
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
public DataSource dataSource1() throws SQLException {
ClassLoader classLoader = this.multitenancyProperties.getDatasource1().getClassLoader();
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource1().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource1().getDriverClassName())
.username(this.multitenancyProperties.getDatasource1().getUsername())
.password(this.multitenancyProperties.getDatasource1().getPassword())
.url(this.multitenancyProperties.getDatasource1().getUrl());
return factory.build();
}
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource2")
public DataSource dataSource2()
throws Exception {
String dataSourceName = "datasource2";
return this.getSecondaryDataSource(dataSourceName);
}
@Bean(name = "dataSource3")
@ConfigurationProperties(prefix = "spring.multitenancy.datasource3")
public DataSource dataSource3()
throws Exception {
String dataSourceName = "datasource3";
return this.getSecondaryDataSource(dataSourceName);
}
private DataSource getSecondaryDataSource(String dataSourceName)
throws Exception {
DataSource d = this.dataSource1();
PreparedStatement preparedStatement = d.getConnection().prepareStatement("SELECT * FROM DATABASECONFIG WHERE DB_NAME = ?");
preparedStatement.setString(1, dataSourceName);
ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.next()) {
// No result found --> throw exception
throw new Exception("Error Finding DB Config for DataSource [" + dataSourceName + "].");
}
DataSourceBuilder factory = DataSourceBuilder
.create()
.driverClassName(resultSet.getString("DRIVER"))
.username(resultSet.getString("USERNAME"))
.password(resultSet.getString("PASSWORD"))
.url(resultSet.getString("URL"));
return factory.build();
}
}发布于 2017-04-06 19:23:36
我会做以下事情:
属性文件
spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update弹簧配置
@Configuration
public class DataSourceConfig {
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
private DataSourceProperties ds;
@Bean
public DataSource dataSource1() {
DataSourceBuilder factory = DataSourceBuilder
.create(ds.getClassLoader())
.driverClassName(ds.getDriverClassName())
.username(ds.getUsername())
.password(ds.getPassword())
.url(ds.getUrl());
return factory.build();
}
@Bean
public DataSource dataSource2() {
createFromDataSource1Conf("key2");
}
@Bean
public DataSource dataSource3() {
createFromDataSource1Conf("key3");
}
private DataSource createFromDataSource1Conf(Object configPrefix) {
// Query db and create datasources
}
}我不太确定以这种方式使用@ConfigurationProperties是否有效,但您可以像现在一样使用它。
@ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
private DataSourceProperties ds;发布于 2017-04-10 19:39:47
将@Configuration类一分为二。在第一个中创建主数据源,然后创建autowire it into the second;使其可用于从数据源@Bean方法。
https://stackoverflow.com/questions/43154067
复制相似问题