package com.bughz.forum.system.config;//包路径
import com.bughz.forum.common.model.MessagesLang;//数据库表对应的实体
import com.bughz.forum.common.service.MessagesLangService;//查询数据库的服务类
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author bughz
* @date 2019/10/17
* describe: 注意继承的类和实现的接口
*/
@Service("messageSource")
public class MessageResource extends AbstractMessageSource implements ResourceLoaderAware {
@SuppressWarnings("unused")
private ResourceLoader resourceLoader;
@Autowired
private MessagesLangService messagesLangService;
/**
* Map切分字符
*/
private static final Map<String, Map<String, String>> LOCAL_CACHE = new ConcurrentHashMap<>(256);
/**
* 启动项目执行reload方法
*/
@PostConstruct
public void init() {
reload();
}
/**
* 该方法为了刷新缓存中的语言,每次修改了数据库后记得调用一下
*/
public void reload() {
LOCAL_CACHE.clear();
LOCAL_CACHE.putAll(loadTexts());
System.out.println("");
}
/**
*
* 描述:TODO
* 加载数据
* @return
*/
public Map<String, Map<String, String>> loadTexts() {
List<MessagesLang> list = messagesLangService.findAll();
if (list.size()>0) {
//因为我只有中文和英文,涉及到其他语言,只需要添加列 和 在这里添加集合即可
final Map<String, String> zhCnMessageResources = new HashMap<>(list.size());
final Map<String, String> enUsMessageResources = new HashMap<>(list.size());
for (MessagesLang ml : list) {
String name = ml.getKey();
String zhText = ml.getZhCN();
String enText = ml.getEnUS();
zhCnMessageResources.put(name, zhText);
enUsMessageResources.put(name, enText);
}
LOCAL_CACHE.put("zh", zhCnMessageResources);
LOCAL_CACHE.put("en", enUsMessageResources);
}
return MapUtils.EMPTY_SORTED_MAP;
}
/**
* 从缓存中取出国际化配置对应的数据 或者从父级获取
* 用于java后台从国际化查询内容
* @param code
* @param locale
* @return
*/
public String getSourceFromCache(String code, Locale locale) {
String language = locale.getLanguage();
Map<String, String> props = LOCAL_CACHE.get(language);
if (null != props && props.containsKey(code)) {
return props.get(code);
} else {
try {
if (null != this.getParentMessageSource()) {
return this.getParentMessageSource().getMessage(code, null, locale);
}
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
return code;
}
}
// 下面三个重写的方法是比较重要的
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader == null ? new DefaultResourceLoader() : resourceLoader);
}
@Override
protected MessageFormat resolveCode(String code, Locale locale) {
String msg = getSourceFromCache(code, locale);
MessageFormat messageFormat = new MessageFormat(msg, locale);
return messageFormat;
}
@Override
protected String resolveCodeWithoutArguments(String code, Locale locale) {
return getSourceFromCache(code, locale);
}
}