[英]Create Spring @Service instance with @Transactional methods manually from Java
假設有@Service
和@Repository
接口,如下所示:
@Repository
public interface OrderDao extends JpaRepository<Order, Integer> {
}
public interface OrderService {
void saveOrder(Order order);
}
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Override
@Transactional
public void saveOrder(Order order) {
orderDao.save(order);
}
}
這是工作應用程序的一部分,一切都配置為訪問單個數據庫,一切正常。
現在,我希望有可能使用純Java和Java代碼中指定的 jdbcUrl自動連接OrderDao來創建OrderService的獨立工作實例 ,如下所示:
final int tenantId = 3578;
final String jdbcUrl = "jdbc:mysql://localhost:3306/database_" + tenantId;
OrderService orderService = someMethodWithSpringMagic(appContext, jdbcUrl);
正如您所看到的,我想向現有的基於Spring的應用程序引入具有每個數據庫策略租戶的 多租戶架構 。
請注意,在使用自己實現的類似jdbcTemplate的邏輯之前,我能夠很容易地實現這一點,並且JDBC事務正確地工作,因此這是非常有效的任務 。
還請注意,我需要非常簡單的事務邏輯來啟動事務,在該事務范圍內的service方法中執行多個請求,然后在異常時提交/回滾。
Web上關於多租戶的大多數解決方案都建議在xml配置和/或使用基於注釋的配置中指定具體的持久性單元,這是非常不靈活的,因為為了添加新的數據庫url應該停止整個應用程序,xml config / annotation code應該更改並啟動應用程序。
所以,基本上我正在尋找一段能夠創建@Service
的代碼,就像Spring在從XML配置/注釋中讀取屬性后在內部創建它一樣。 我也在考慮使用ProxyBeanFactory
,因為Spring使用AOP
來創建服務實例(所以我想簡單的舊的可重用OOP不是這里的方法)。
Spring是否足夠靈活 ,允許這種相對簡單的代碼重用案例 ?
任何提示將不勝感激 ,如果我找到這個問題的完整答案,我會在這里發布給后代:)
為帶注釋的服務創建事務代理並不是一項艱巨的任務,但我不確定您是否確實需要它。 為tenantId選擇一個數據庫我想你只需要專注於DataSource
接口。
例如,使用簡單的驅動程序托管數據源:
public class MultitenancyDriverManagerDataSource extends DriverManagerDataSource {
@Override
protected Connection getConnectionFromDriverManager(String url,
Properties props) throws SQLException {
Integer tenant = MultitenancyContext.getTenantId();
if (tenant != null)
url += "_" + tenant;
return super.getConnectionFromDriverManager(url, props);
}
}
public class MultitenancyContext {
private static ThreadLocal<Integer> tenant = new ThreadLocal<Integer>();
public static Integer getTenantId() {
return tenant.get();
}
public static void setTenatId(Integer value) {
tenant.set(value);
}
}
當然,如果要使用連接池,則需要對其進行詳細說明,例如每個租戶使用一個連接池。
HIbernate 對多租戶提供開箱即用的支持,在嘗試自己之前先檢查一下。 Hibernate需要一個MultiTenantConnectionProvider
和CurrentTenantIdentifierResolver
,其默認實現開箱即用,但您始終可以編寫自己的實現。 如果它只是一個模式更改,實際上很容易實現(在返回連接之前執行查詢)。 否則,保存數據源地圖並從中獲取實例,或創建新實例。
大約8年前,我們已經編寫了一個通用解決方案, 此處已記錄在案,代碼就在這里 。 它不是特定於休眠的,並且可以與基本上需要切換的任何東西一起使用。 我們將它用於DataSource
以及一些與Web相關的東西(其中包括其他內容)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.