| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package jnpf.i18n.provider;
- import cn.hutool.cache.CacheUtil;
- import cn.hutool.cache.impl.TimedCache;
- import jnpf.base.UserInfo;
- import jnpf.config.ConfigValueUtil;
- import jnpf.constant.GlobalConst;
- import jnpf.constant.model.MCode;
- import jnpf.util.TenantHolder;
- import jnpf.util.UserProvider;
- import lombok.extern.slf4j.Slf4j;
- import java.util.Locale;
- import java.util.Properties;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * 国际化语言翻译
- */
- @Slf4j
- public class MyI18nMessageProvider implements I18nMessageProvider {
- private ConfigValueUtil configValueUtil;
- private final long CACHE_TIME = 48 * 60 * 60000L;
- // 未使用的情况下, 默认48小时失效, 使用后重新计算缓存时效
- private TimedCache<String, TimedCache<String, Properties>> tenantMessageProperties = CacheUtil.newTimedCache(CACHE_TIME);
- // 翻译内容提供者
- private DynamicMessageProvider dynamicMessageProvider;
- // 租户语言加载锁
- private final ConcurrentHashMap<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
- private Properties emptyProperties = new Properties();
- public MyI18nMessageProvider(ConfigValueUtil configValueUtil, DynamicMessageProvider dynamicMessageProvider) {
- this.configValueUtil = configValueUtil;
- this.dynamicMessageProvider = dynamicMessageProvider;
- // 执行定时清理
- tenantMessageProperties.schedulePrune(CACHE_TIME);
- }
- public void removeTenantCache(String tenantId) {
- tenantMessageProperties.remove(tenantId);
- }
- public void loadTenantMessage(String tenantId, Locale locale) {
- Properties i18nListProperties = dynamicMessageProvider.getI18nListProperties(locale);
- TimedCache<String, Properties> tenantProperties = tenantMessageProperties.get(tenantId);
- if (tenantProperties == null) {
- tenantProperties = CacheUtil.newTimedCache(CACHE_TIME);
- tenantMessageProperties.put(tenantId, tenantProperties);
- }
- if (i18nListProperties == null) {
- // 语言加载失败, 一分钟后重新加载, 避免高频请求
- tenantProperties.put(locale.toLanguageTag(), emptyProperties, 60000L);
- } else {
- // 无论是否有内容返回都是加载成功, 如果properties为空没有翻译数据, 服务端新增翻译时会清空缓存重新加载
- tenantProperties.put(locale.toLanguageTag(), i18nListProperties);
- }
- }
- @Override
- public MCode getI18nMessage(String code, Locale locale) {
- UserInfo userInfo = UserProvider.getUser();
- // 未登录不获取
- if (userInfo.getToken() == null) {
- return null;
- }
- // 默认租户或者当前租户
- String tenantId = GlobalConst.DEFAULT_TENANT_VALUE;
- if (configValueUtil.isMultiTenancy()) {
- tenantId = TenantHolder.getDatasourceId();
- }
- // 开启租户未获取到租户 不进行翻译获取
- if (tenantId != null) {
- // 租户配置中的语言配置
- String languageTag = locale.toLanguageTag();
- if (!tenantMessageProperties.containsKey(tenantId) || !tenantMessageProperties.get(tenantId).containsKey(languageTag)) {
- // 租户其他线程正在加载多语言则直接返回
- ReentrantLock lock = lockMap.computeIfAbsent(tenantId, k -> new ReentrantLock());
- boolean isLock = false;
- try {
- isLock = lock.tryLock();
- if (isLock) {
- loadTenantMessage(tenantId, locale);
- } else {
- log.debug("[{}]语言加载中, 直接返回", tenantId);
- return null;
- }
- } finally {
- if (isLock) {
- lock.unlock();
- }
- }
- }
- Properties languageProperty = tenantMessageProperties.get(tenantId).get(languageTag, false);
- if (languageProperty != null) {
- Object message = languageProperty.get(code);
- if (message != null) {
- return new MCode("", code, message.toString());
- }
- }
- }
- return null;
- }
- }
|