Я пытаюсь реализовать многопользовательскую архитектуру в своем проекте.Я имею в виду пример "http://anakiou.blogspot.com/2015/08/multi-tenant-application-with-spring.html"". В этом примере все работает нормально. Но проблема в этом примере заключается в том, что всякий раз, когда добавляется новый источник данных, мы должны добавить его вручную. Но я хочу что-то вроде динамического добавления источника данных без перезапуска приложения..
Это мое application.properties
spring.jpa.hibernate.ddl-auto=none
spring.thymeleaf.cache=false
spring.datasource.datasource1.url=jdbc:mysql://localhost:3306/tenant_1
spring.datasource.datasource1.username=root
spring.datasource.datasource1.password=root
spring.datasource.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.datasource2.url=jdbc:mysql://localhost:3306/tenant_2
spring.datasource.datasource2.username=root
spring.datasource.datasource2.password=root
spring.datasource.datasource2.driver-class-name=com.mysql.jdbc.Driver
Это DataSourceConfig.java
package com.anakiou.mt.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
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.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Bean(name = { "dataSource", "dataSource1" })
@ConfigurationProperties(prefix = "spring.datasource.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();
}
@Primary
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.datasource.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();
}
}
MultitenancyProperties.java
package com.anakiou.mt.config;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
@ConfigurationProperties("spring.datasource")
public class MultitenancyProperties {
@NestedConfigurationProperty
private DataSourceProperties datasource1;
@NestedConfigurationProperty
private DataSourceProperties datasource2;
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;
}
}
DataSourceBasedMultiTenantConnectionProviderImpl.Ява
package com.anakiou.mt.util;
import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends
AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1";
@Autowired
private DataSource dataSource1;
@Autowired
private DataSource dataSource2;
private Map<String, DataSource> map;
@PostConstruct
public void load() {
map = new HashMap<>();
map.put("tenant_1", dataSource1);
map.put("tenant_2", dataSource2);
}
@Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}