2015년 4월 21일 화요일

EhCache Spring에서 사용하기 JavaConfig

Context설정
package com.lge.apip.config;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
@EnableCaching
@ComponentScan(basePackages="com.lge.apip.mgmt")
public class EhcacheContext {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyBatisContext.class);
    @Bean(name = "ehcache")
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("/conf/cache/ehcache.xml"));
        return ehCacheManagerFactoryBean;
    }
    @Bean(name = "cacheManager")
    public EhCacheCacheManager cacheManager() {
        return new EhCacheCacheManager(ehCacheManagerFactoryBean().getObject());
    }
    @PostConstruct
    public void postConstruct() {
        LOGGER.info("Cache Created");
    }
}

cache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
         updateCheck="false" monitoring="autodetect" dynamicConfig="false"
         maxBytesLocalHeap="75%" name="debop4j-cache">

    <diskStore path="java.io.tmpdir"/>

    <cache name="MenuCache"
           eternal="true"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"
           statistics="false"/>
         
    <cache name="CodeCache"
           eternal="true"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"
           statistics="false"/>
         
</ehcach

LRU(Least Recently Used)는 교체 전략 중의 하나로 최근 사용이 가장 적은 것부터 버리는 방식이다.

실제 cache 설정 코드

ServiceImpl.java
/* (non-Javadoc)
* @see com.skp.openplatform.backoffice.ocpo.menu.service.MenuService#getTreeMenuList()
*/
@Override
@Cacheable(value = "MenuCache",  key = "#root.target.MENU_TOTAL", condition="#searchRequest.query.size() == 0 && #searchRequest.pageInfo == null")
public List<Menu> getTreeMenuList(SearchRequest searchRequest) {
   searchRequest.setData(); //query 데이타 셋팅
List<Menu> menuList = menuMapper.selectTreeMenuList(searchRequest);
List<Menu> newMenuList = new ArrayList<Menu>();

if(menuList != null && menuList.size() > 0) {
long baseMenuId = menuList.get(0).getBaseMenuId();
newMenuList.add(menuList.get(0));
for(int index = 1 ; index < menuList.size() ; index++ ) {
Menu menu = menuList.get(index);
if( baseMenuId == menu.getBaseMenuId() ) {
newMenuList.add(0,menu);
} else {
for( int j = 0 ; j < newMenuList.size() ; j++ ) {
if( menu.getBaseMenuId() == newMenuList.get(j).getOppositeMenuId() ) {
newMenuList.add(j+1, menu);
continue;
}
}
}
}
}
return newMenuList;
}

Caching 컨트롤

conditional 속성과 SpEL 표현식으로 ture나 false 평가식을 만들 수 있다. 해당 표현식이 true면 캐싱하고, false명 캐싱하지 않는다.

@Cacheable(value = "MenuCache",  key = "#root.target.MENU_TOTAL", condition="#searchRequest.query.size() == 0 && #searchRequest.pageInfo == null")

아래의 목록은 key와 condition에서 사용할 수 있는 spel 속성 값이다.

표 28.1. Cache SpEL available metadata
이름위치설명예제
methodNameroot 객체실행될 메서드 이름#root.methodName
methodroot 객체실행될 메서드#root.method.name
targetroot 객체실행될 타겟 객체#root.target
targetClassroot 객체실행될 타겟 클래스#root.targetClass
paramsroot 객체타겟을 실행할 때 사용하는 인자 목록#root.params[0]
cacahesroot 객체현재 메서드 실행할 때 사용하는 캐시 컬렉션#root.cacahes[0].name
parameter nameevalucation 컨텍스트메서드 매개변수 이름iban 또는 p0
@CacheEvict 애노테이션

캐쉬를 삭제 할때 사용한다. 특정 엔트리만 삭제할 수 있고  모든 캐쉬 데이타를 삭제할 수도 있다. Cacheable와 같이 key, condition을 모두 사용할 수 있다.

@CacheEvict(value = "CodeCache", allEntries=true)

allEntries 이 옵션은 캐시 영역을 비워야 할 때 유용하다. 키를 명시해도 적용되지 않기 때문에 무시한다.

댓글 없음:

댓글 쓰기