Ehcache Configuration : Dynamic Setting
반응형
cache.xml
<caches>
<cache name="good"
maxEntriesLocalHeap="10000"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
eternal="false"
memoryStoreEvictionPolicy="LFU">
<persistence strategy="localTempSwap" />
</cache>
<cache name="good2"
maxEntriesLocalHeap="10000"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
eternal="false"
memoryStoreEvictionPolicy="LFU">
<persistence strategy="localTempSwap" />
</cache>
<cache name="good3"
maxEntriesLocalHeap="10000"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
eternal="false"
memoryStoreEvictionPolicy="LFU">
<persistence strategy="localTempSwap" />
</cache>
</caches>
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
</ehcache>
/**/cache.xml 을 여러개 만들어 Ant style path pattern 으로 모두 읽어서 아래와 같이 반영하면 된다.
/**
* @author Seok Kyun. Choi. 최석균 (Syaku)
* @site http://syaku.tistory.com
* @since 2017. 9. 13.
*/
public class CreateXmlConfiguration {
private final Logger logger = LoggerFactory.getLogger(CreateXmlConfiguration.class);
private final String TEMPLATE_FILE = "ehcache.xml";
private final String CACHE_FILE = "cache.xml";
// todo 템플릿 파일을 읽는 다.
// @Test
public Document getTemplateLoader() throws Exception {
ClassPathResource resource = new ClassPathResource(TEMPLATE_FILE);
if (resource.exists()) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
return dbf.newDocumentBuilder().parse(resource.getFile());
}
return null;
}
// todo 대상 경로의 cache.xml 파일을 로드한다.
// @Test
public List<Node> getCacheLoader() throws Exception {
List<Node> result = new ArrayList<>();
ClassPathResource resource = new ClassPathResource(CACHE_FILE);
if (resource.exists()) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document document = dbf.newDocumentBuilder().parse(resource.getFile());
Element rootElement = document.getDocumentElement();
NodeList list = rootElement.getChildNodes();
int length = list.getLength();
for (int i = 0; i < length; i++) {
Node node = list.item(i);
if ("cache".equals(node.getNodeName())) {
result.add(node);
}
}
}
return result;
}
// todo 템플릿에 cache.xml 데이터를 삽입한다.
// @Test
public InputStream getInputStream() throws Exception {
Document document = this.getTemplateLoader();
Element rootElement = document.getDocumentElement();
List<Node> nodes = this.getCacheLoader();
for (Node node : nodes) {
Node newNode = document.importNode(node, true);
rootElement.appendChild(newNode);
}
NodeList list = rootElement.getChildNodes();
int length = list.getLength();
for (int i = 0; i < length; i++) {
Node node = list.item(i);
logger.debug(node.getNodeName());
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StringWriter xmlAsWriter = new StringWriter();
StreamResult result = new StreamResult(xmlAsWriter);
TransformerFactory.newInstance().newTransformer().transform(source, result);
return new ByteArrayInputStream(xmlAsWriter.toString().getBytes("UTF-8"));
}
// todo CacheManager 생성하기
@Test
public void test() throws Exception {
InputStream inputStream = this.getInputStream();
Configuration configuration = ConfigurationFactory.parseConfiguration(this.getInputStream());
EhcacheFactoryBean factoryBean = new EhcacheFactoryBean();
factoryBean.setConfiguration(configuration);
factoryBean.afterPropertiesSet();
}
}
/**
* @author Seok Kyun. Choi. 최석균 (Syaku)
* @site http://syaku.tistory.com
* @since 16. 7. 28.
* @see org.springframework.cache.ehcache.EhCacheManagerFactoryBean
*/
public class EhcacheFactoryBean implements FactoryBean<CacheManager>, InitializingBean, DisposableBean {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private CacheManager cacheManager;
private String cacheManagerName = "cacheManager";
private boolean acceptExisting = false;
private boolean shared = false;
private boolean locallyManaged = true;
private Configuration configuration;
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
public void setCacheManagerName(String cacheManagerName) {
this.cacheManagerName = cacheManagerName;
}
public void setAcceptExisting(boolean acceptExisting) {
this.acceptExisting = acceptExisting;
}
public void setShared(boolean shared) {
this.shared = shared;
}
public void setLocallyManaged(boolean locallyManaged) {
this.locallyManaged = locallyManaged;
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
}
@Override
public void afterPropertiesSet() throws CacheException {
logger.info("Initializing EhCache CacheManager");
if (this.cacheManagerName != null) {
configuration.setName(this.cacheManagerName);
}
if (this.shared) {
// Old-school EhCache singleton sharing...
// No way to find out whether we actually created a new CacheManager
// or just received an existing singleton reference.
this.cacheManager = CacheManager.create(configuration);
}
else if (this.acceptExisting) {
// EhCache 2.5+: Reusing an existing CacheManager of the same name.
// Basically the same code as in CacheManager.getInstance(String),
// just storing whether we're dealing with an existing instance.
synchronized (CacheManager.class) {
this.cacheManager = CacheManager.getCacheManager(this.cacheManagerName);
if (this.cacheManager == null) {
this.cacheManager = new CacheManager(configuration);
}
else {
this.locallyManaged = false;
}
}
}
else {
// Throwing an exception if a CacheManager of the same name exists already...
this.cacheManager = new CacheManager(configuration);
}
}
@Override
public CacheManager getObject() {
return this.cacheManager;
}
@Override
public Class<? extends CacheManager> getObjectType() {
return (this.cacheManager != null ? this.cacheManager.getClass() : CacheManager.class);
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void destroy() {
if (this.locallyManaged) {
logger.info("Shutting down EhCache CacheManager");
this.cacheManager.shutdown();
}
}
}
반응형