Spring 제공하는 캐시 추상화를 통해 캐시 구현에 대해 신경 쓸 필요없이
개발자는 어노테이션을 통해 쉽게 캐싱 기능을 사용할 수 있다.
개발자는 캐시를 사용하는데 있어 비즈니스 로직 코드가 변경되지 않을까
하는 것에 대해 망설일 필요 없이 쉽게 인프라스트럭쳐를 변경할 수 있다.
개발자가 별도의 서드파티 라이브러리를 추가하지 않았다면 default로
local memory에 저장되는 ConcurrentMap 기반의 CacheManager인 ConcurrentMapCacheManager가 Bean으로 자동 등록된다.
개발자의 의도에 따라 필요하다면
EHCacheCacheManager 혹은 RedisCacheManager를
CacheManager로 등록해 사용할 수 있다.
기본적으로 Spring boot에서 EHCache를 사용하기위해
아래와 같은 dependency를 추가한다.
<!— Spring의 캐시 추상화를 사용하기 위해 추가 —>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!— ehcache를 사용하기 위해 추가 —>
<!-- 만약 ehcache를 사용하지 않고 default cachemanager를
사용할 경우 해당 dependency 미포함 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.6</version>
</dependency>
그 후 Spring Boot에서 어노테이션 기반의 캐시를 사용할 수 있도록 하기 위해 @EnableCache 을 @Configration 클래스에 추가한다.
ex) Default로 제공되는 cachemanager를 사용할 경우
@Configuration
@EnableCaching
public class CacheConfig {
// default로 사용되는 cachemanager
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(“…”);
}
}
만약 CacheManger를 커스터마이징 하길 원한다면 CacheManagerCustomizer 인터페이스를 구현해 Bean으로 등록하면 된다.
@Component
public class CustomCacheManger implements CacheManagerCustomizer<ConcurrentMapCacheManager> {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setAllowNullValues(false);
…
…
}
}
ex) Ehcachemanager를 사용할 경우
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
// ehcache 설정 정보를 담은 xml 위치
ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache-config.xml"));
// cachemanager의 싱글톤 여부를 지정하는 값으로 true로 설정시 만약 기존 cachemanager가 존재하지 않을 경우 새로 생성
ehCacheManagerFactoryBean.setShared(true);
return ehCacheManagerFactoryBean;
}
@Bean
EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean ehCacheManagerFactoryBean) {
EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
ehCacheCacheManager.setCacheManager(ehCacheManagerFactoryBean.getObject());
return ehCacheCacheManager;
}
}
Ehcache-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir" />
<cache name=“캐시 이름”
maxEntriesLocalHeap="1000"
maxEntriesLocalDisk="10000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="10"
timeToLiveSeconds="10"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
maxEntriesLocalHeap :
힙 메모리에서 캐시를 사용할 수 있는 pool 사이즈로 GC의 대상이 됨
maxEntriesLocalDisk :
디스크에서 캐시를 사용할 수 있는 pool 사이즈
diskStore :
스풀링 공간을 설정하는 것으로 여러개의 cachemanager를 사용할 경우 등록해주는 것이 좋음
eternal :
true일 경우 캐시 만료 설정을 무시하고 캐시가 삭제되지 않음, 기본 설정은 false
timeToldleSeconds :
지정한 시간동안 캐시가 조회되지 않을 경우 제거됨, 0일 경우 사용하지 않음, 기본 설정은 0
timeToLiveSeconds :
지정한 시간이 지나면 캐시가 제거됨, 0일 경우 사용하지 않음, 기본 설정은 0
diskPersistent :
JVM이 재가동시 현재 저장되어있는 캐시를 모두 저장할 지의 여부, 기본 설정은 false
diskSpoolBufferSizeMB :
스풀 버퍼의 크기를 지정, 만약 OutOfMemory exception이 발생할 경우 크기를 낮추는 것을 권장
memoryStoreEvictionPolicy :
maxEntriesLocalHeap 이 값의 최대치에 도달했을 경우 해당 설정에 따라 캐시가 제거됨
ㄴLRU: 가장 오랫동안 사용이 안된 것 부터 제거.
ㄴFIFO: 가장 먼저 저장된 것 부터 제거.
ㄴLFU: 사용 빈도가 가장 적은 것 부터 제거.
transactionalMode: 트랜잭션 설정