数据源之间的多租户动态切换不起作用
Multi-tenancy Dynamic switch between Datasources is not working
我正在尝试在我的 spring 启动应用程序中实施多租户。我指的是“http://anakiou.blogspot.com/2015/08/multi-tenant-application-with-spring.html”的例子。在此示例中,一切正常。但在我的代码中,数据源之间的切换没有发生。
在我的 DataSourceConfig.java 中,我在声明 3 个 Bean 时遇到问题,所以我正在使用 @Primary 注释。如果我删除 @Primary 注释,我会收到以下错误
' Parameter 1 of method liquibase in com.config.DatabaseConfiguration required a single bean, but 3 were found:
- dataSource: defined by method 'dataSource1' in class path resource [com/config/DataSourceConfig.class]
- dataSource2: defined by method 'dataSource2' in class path resource [com/config/DataSourceConfig.class]
- dataSource3: defined by method 'dataSource3' in class path resource [com/config/DataSourceConfig.class] '
但是,如果我使用@Primary 批注而不考虑租户ID,它会将数据存储在用@Primary 批注的DataSource 中。所以没有发生 DataSource 的切换。
这是我的 DataSourceConfig class
package com.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Required;
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;
import com.netflix.governator.annotations.binding.Secondary;
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Primary
@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();
}
@Bean(name = {"dataSource2"})
@ConfigurationProperties(prefix = "spring.datasource.datasource2")
public DataSource dataSource2(@Qualifier("dataSource1") DataSource dataSource1) {
System.out.println("Entered to 2");
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.datasource.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();
}}
禁用 Spring 的 DataSourceAutoConfiguration 并提供我们的多租户 DataSourceConfig。这将从 MultitenancyProperties 加载属性,而 MultitenancyProperties 又由 application.properties 配置并相应地配置我们的数据源。要排除 DataSourceAutoConfiguration 使用 @EnableAutoConfiguration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
我正在尝试在我的 spring 启动应用程序中实施多租户。我指的是“http://anakiou.blogspot.com/2015/08/multi-tenant-application-with-spring.html”的例子。在此示例中,一切正常。但在我的代码中,数据源之间的切换没有发生。
在我的 DataSourceConfig.java 中,我在声明 3 个 Bean 时遇到问题,所以我正在使用 @Primary 注释。如果我删除 @Primary 注释,我会收到以下错误
' Parameter 1 of method liquibase in com.config.DatabaseConfiguration required a single bean, but 3 were found:
- dataSource: defined by method 'dataSource1' in class path resource [com/config/DataSourceConfig.class]
- dataSource2: defined by method 'dataSource2' in class path resource [com/config/DataSourceConfig.class]
- dataSource3: defined by method 'dataSource3' in class path resource [com/config/DataSourceConfig.class] '
但是,如果我使用@Primary 批注而不考虑租户ID,它会将数据存储在用@Primary 批注的DataSource 中。所以没有发生 DataSource 的切换。
这是我的 DataSourceConfig class
package com.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Required;
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;
import com.netflix.governator.annotations.binding.Secondary;
@Configuration
public class DataSourceConfig {
@Autowired
private MultitenancyProperties multitenancyProperties;
@Primary
@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();
}
@Bean(name = {"dataSource2"})
@ConfigurationProperties(prefix = "spring.datasource.datasource2")
public DataSource dataSource2(@Qualifier("dataSource1") DataSource dataSource1) {
System.out.println("Entered to 2");
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.datasource.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();
}}
禁用 Spring 的 DataSourceAutoConfiguration 并提供我们的多租户 DataSourceConfig。这将从 MultitenancyProperties 加载属性,而 MultitenancyProperties 又由 application.properties 配置并相应地配置我们的数据源。要排除 DataSourceAutoConfiguration 使用 @EnableAutoConfiguration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})