背景
SAAS应用支持多租户模式,一个租户对应一个数据库,数据库已通过AOP支持动态切换;
项目中使用了EhCache做为缓存,原先的设计key值中没有租户id,所有多租户会出现相同的key;
如果所有使用缓存的地方在key中添加租户id,改动太繁琐,也不符合框架设计;
所以框架设计上还是通过切面实现更合理,符合框架设计。
实现原理
1. 在缓存查询时通过AOP动态切换cacheName,在cacheName中拼接租户ID;
@Aspect
@Component
public class DynamicCacheNameAop {
@Pointcut("execution(* org.springframework.cache.support.AbstractCacheManager.getCache(..))")
public void getCache() {
}
@Around(value = "getCache()")
public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] args = proceedingJoinPoint.getArgs();
if (args != null) {
args[0] += RequestThreadLocal.getTenantId();
}
return proceedingJoinPoint.proceed(args);
}
}
2. cacheName不存在时,动态生成新的cache。
@Component
public class DynamicEhCacheNameGenerator extends EhCacheCacheManager {
@Override
protected Cache getMissingCache(String name) {
Cache missingCache = super.getMissingCache(name);
if (missingCache == null) {
getCacheManager().addCache(name);
missingCache = new EhCacheCache(getCacheManager().getCache(name));
}
return missingCache;
}
}