我正在尝试创建一个多租户Web应用程序,并找到了一个很好的教程here。这解释了如何配置MVC以查找新租户(使用CurrentTenantIdentifierResolver
和扩展HandlerInterceptorAdapter
的MultiTenancyInterceptor),如何为三个不同的租户配置三个不同的数据源,以及如何提供正确的数据源通过扩展AbstractDataSourceBasedMultiTenantConnectionProviderImpl
现在,这是一个很好的起点,让我了解春天和冬眠的多租户是如何工作的,但我想进一步推动这一点,我想做到让租户完全充满活力,即我不要假设申请可以有多少租户。
这就是我的想法:
之后,基本的多租户结构已在上述链接中描述:每当最终用户向浏览器发出请求时,服务器将详细说明租户并返回正确的数据源以查找要使用的数据库
任何人都可以指点我一些资源,如果之前已经做过(我搜索了很多但没有让我开始),或者提供一些关于使用哪个Spring类/配置来实现这个目标的建议?
提前致谢
答案 0 :(得分:2)
这就是我最终做的事情,如果有人有此需要的话。 任何进一步的扩展,或者关于最佳做法侵权的评论都将受到欢迎。
扩展DataSourceProvider
的{{1}}必须覆盖两种方法
AbstractDataSourceBasedMultiTenantConnectionProviderImpl
返回一个selectAnyDataSource
,它由Spring实例化,通常用于实例化应用程序的数据源。@Autowired DataSource
执行以下操作:
selectDataSource(String tenant)
,其属性取自租户配置文件夹中的application.properties文件DataSourceProperties
创建并返回一个新的DataSource,使用以前实例化的DataSourceProperties中的字段作为属性(因为Spring会从数据库URL动态地为您提供驱动程序类名称)。此处提供的代码,随时可以使用它:
DataSourceBuilder
答案 1 :(得分:0)
这是完整的代码。我希望这能对我有所帮助,因为我在此之前也遭受了痛苦。
@RestController
@RequestMapping(value = "/accounts", headers = "Accept=application/json")
public class AppController {
@Autowired
UserService service;
@Autowired
AppService appService;
////////working on dynamic loading of datasource
@Autowired
Map<String, DataSource> dataSourcesMtApp;
public void updateDataSource(String url, String username, String password, String tenant) {
try {
DataSourceBuilder factory1 = DataSourceBuilder.create(MultiTenancyJpaConfiguration.class.getClassLoader()).url(url)
.username(username).password(password)
.driverClassName("com.mysql.jdbc.Driver");
dataSourcesMtApp.put(tenant, factory1.build());
System.out.println("Size:......................................................" + dataSourcesMtApp.size());
} catch (Exception ex) {
Logger.getLogger(AppController.class.getName()).log(Level.SEVERE, null, ex);
}
}
@PostMapping("/create-account")
public Response createAccount(@RequestBody ConnectionParams request) {
String tenant = ConnectionUtils.initializeDatabase(request.getDatabase(), request.getDbusername(), request.getDbpassword());
updateDataSource("jdbc:mysql://localhost:3306/" + request.getDatabase() + "?useSSL=false", request.getDbusername(), request.getDbpassword(), tenant);
TenantContextHolder.setTenantId(tenant);
Users user = new Users();
user.setPassword(request.getLoginpassword());
user.setUsername(request.getLoginusername());
user.setTenant(tenant);
user = service.save(user);
String response = "Account Setup Completed TenantId: " + tenant + " Username: " + user.getUsername();
Response rp = new Response();
rp.setResult(response);
return rp;
}
}