1.简介
使用EhCache缓存资源,使用ResourcePatternResolver从多个文件中加载资源
2.源文件
1)EhCacheResourceBundles
package com.siyuan.test.spring;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import net.sf.ehcache.CacheManager;
public class EhCacheResourceBundles {
private static final Logger LOGGER =
LoggerFactory.getLogger(EhCacheResourceBundles.class);
private static final String RESOURCE_FILE_SUFFIX = ".properties";
private CacheManager cacheManager;
private Map<Locale, EhCacheResourceBundle> resourceBundles =
new HashMap<Locale, EhCacheResourceBundle>();
/**
* EhCache configuration location
* Spring Resource path, a absolute path,
* Used to configure the EhCache
*/
public EhCacheResourceBundles(String configuration, String resourcePatterns)
throws IOException {
if (StringUtils.isBlank(configuration)) {
throw new IllegalArgumentException(
"argument[configuration] can not be blank");
}
if (StringUtils.isBlank(resourcePatterns)) {
throw new IllegalArgumentException(
"argument[resourcePatterns] can not be blank");
}
initCacheManager(configuration);
initResourceBundles(resourcePatterns);
}
private void initCacheManager(String configuration) throws IOException {
ResourcePatternResolver resourceResolver =
new PathMatchingResourcePatternResolver();
Resource[] resources = resourceResolver.getResources(configuration);
if (resources.length == 0) {
throw new IllegalArgumentException("configuration["
+ configuration +"] can not be resolved to a resource");
}
InputStream input = null;
try {
LOGGER.info("init CacheManager by the configuration[{}] ", resources[0]);
input = resources[0].getInputStream();
cacheManager = CacheManager.newInstance(input);
} finally {
if (input != null) {
input.close();
}
}
}
private void initResourceBundles(String resourcePatterns) throws IOException {
LOGGER.info("load resource from [{}]", resourcePatterns);
ResourcePatternResolver resourceResolver =
new PathMatchingResourcePatternResolver();
String[] resourcePatternArray = resourcePatterns.split(",");
for (String resourcePattern : resourcePatternArray) {
LOGGER.info("load resource from [{}]", resourcePattern);
Resource[] resources = resourceResolver.getResources(resourcePattern);
for (Resource resource : resources) {
loadResource(resource);
}
}
}
private void loadResource(Resource resource) throws IOException {
String fileName = resource.getFilename();
if (!fileName.endsWith(RESOURCE_FILE_SUFFIX)) {
LOGGER.warn("file[{}] does not ended with [{}], will be omitted",
resource, RESOURCE_FILE_SUFFIX);
return;
}
InputStream input = null;
try {
//
Locale locale = getLocale(fileName);
if (locale == null) {
LOGGER.warn("can not resolve locale from file[{}] by name, "
+ "and the file will be omitted, please make the file name "
+ "match XXX_xx.properties or XXX_xx_XX.properties pattern",
fileName);
return;
}
EhCacheResourceBundle resourceBundle = resourceBundles.get(locale);
if (resourceBundle == null) {
LOGGER.debug("no EhCacheResourceBundle is corresponding to the "
+ "locale[{}], will create one", locale);
cacheManager.addCache(locale.toString());
resourceBundle = new EhCacheResourceBundle(
cacheManager.getCache(locale.toString()));
resourceBundles.put(locale, resourceBundle);
}
input = resource.getInputStream();
Properties properties = new Properties();
properties.load(input);
LOGGER.info("load messages from [{}]", resource);
for (Object key : properties.keySet()) {
resourceBundle.addMessage((String) key,
properties.getProperty((String) key));
}
} finally {
if (input != null) {
input.close();
}
}
}
private Locale getLocale(String fileFullName) {
Locale locale = null;
String fileName = fileFullName.substring(0,
fileFullName.lastIndexOf(RESOURCE_FILE_SUFFIX));
String[] fileInfos = fileName.split("_");
if (fileInfos.length == 2) {
locale = new Locale(fileInfos[1]);
} else if (fileInfos.length == 3) {
locale = new Locale(fileInfos[1], fileInfos[2]);
}
LOGGER.debug("locale[{}] is resolved from the fileName[{}]",
locale, fileFullName);
return locale;
}
public String getMessage(String key, Locale locale) {
EhCacheResourceBundle resourceBundle = resourceBundles.get(locale);
if (resourceBundle == null) {
LOGGER.warn("no EhCacheResourceBundle is corresponding to the "
+ "locale[{}]", locale);
return null;
}
return resourceBundle.getString(key);
}
public String getMessage(String key, Locale locale, Object...arguments) {
String messageFmt = getMessage(key, locale);
if (messageFmt == null) {
return null;
}
return new MessageFormat(messageFmt).format(arguments);
}
}
2)EhCacheResourceBundle
package com.siyuan.test.spring;
import java.util.Enumeration;
import java.util.ResourceBundle;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
public class EhCacheResourceBundle extends ResourceBundle {
private Cache cache;
public EhCacheResourceBundle(Cache cache) {
this.cache = cache;
}
public void addMessage(String key, String value) {
cache.put(new Element(key, value));
}
@Override
protected Object handleGetObject(String key) {
Element value = cache.get(key);
if (key == null) {
return null;
}
return value.getObjectValue();
}
@Override
public Enumeration<String> getKeys() {
throw new UnsupportedOperationException(
"EhCacheResourceBundle does not support enumerating its keys");
}
}
3)ehcache-i18n.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false" monitoring="autodetect" dynamicConfig="true"> <defaultCache eternal="true" maxEntriesLocalHeap="0" /> </ehcache>
4)资源文件
|-i18n
|-en_US
|-folder
|-test_en_US.properties
test.key1=test.key1.en_US {0}
|-test_en_US.properties
test.key=test.key.en_US
|-zh
|-folder
|-test_zh.properties
test.key1=test.key1.zh {0}
|-test_zh.properties
test.key=test.key.zh
5)EhCacheResourceBundlesTest
import java.io.IOException;
import java.util.Locale;
import com.siyuan.test.spring.EhCacheResourceBundles;
public class EhCacheResourceBundlesTest {
public static void main(String[] args) throws IOException {
EhCacheResourceBundles resourceBundles
= new EhCacheResourceBundles("classpath:ehcache-i18n.xml", "classpath*:i18n/**/*.properties");
System.out.println(resourceBundles.getMessage("test.key", new Locale("zh")));
System.out.println(resourceBundles.getMessage("test.key", new Locale("en", "US")));
System.out.println(resourceBundles.getMessage("test.key1", new Locale("zh"), "test zh"));
System.out.println(resourceBundles.getMessage("test.key1", new Locale("en", "US"), "test en_US"));
}
}
运行结果
test.key.zh test.key.en_US test.key1.zh test zh test.key1.en_US test en_US
3.附件
程序源代码