안녕하세요
Spring 5 와 ehcache 3.9 적용 방법 입니다.
1.pom.xml
제가 쓰는 스프링 버전은 5.3.2이기 때문에 spring-context-support도 5.3.2 버전을 사용 하였습니다.
현재 기준 전부 최신 버전 입니다.
<!-- ehcache3 -->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.0</version>
</dependency>
<!-- JSR107 API and SPI -->
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.1</version>
</dependency>
<!-- spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.2</version>
</dependency>
2. *-context.xml
application-context.xml에 아래 내용을 추가해 줍니다.
저는 cache-context.xml이라고 따로 만들었습니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<cache:annotation-driven cache-manager="ehCacheManager" />
<bean id="ehCacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
<property name="cacheManager">
<bean class="org.springframework.cache.jcache.JCacheManagerFactoryBean"
p:cacheManagerUri="classpath:ehcache.xml" />
</property>
</bean>
</beans>
3. ehcache.xml
위에서 설정한 cacheManagerUri의 위치에 ehcache.xml 파일을 생성합니다.
내용
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ehcache.org/v3" xmlns:jsr107="http://www.ehcache.org/v3/jsr107" xsi:schemaLocation=" http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd"> <cache-template name="defaultCacheTemplate"> <listeners> <listener> <class>com.trandent.log.CacheLogger</class> <event-firing-mode>ASYNCHRONOUS</event-firing-mode> <event-ordering-mode>UNORDERED</event-ordering-mode> <events-to-fire-on>CREATED</events-to-fire-on> <events-to-fire-on>EXPIRED</events-to-fire-on> <events-to-fire-on>EVICTED</events-to-fire-on> </listener> </listeners> </cache-template> <cache alias="boardList" uses-template="defaultCacheTemplate"> <expiry> <ttl unit="hours">1</ttl> </expiry> <heap unit="entries">200</heap> </cache> </config>
3-1. 샘플은 boardList에 캐시를 적용하였습니다.
boardList의 경우 1시간에 캐시는 200개 까지로 설정하였습니다.
여기서 설정한 alias의 값이 서비스에서 사용됩니다.
3-2. com.trandent.log.CacheLogger : 캐시 관련 로그를 찍기 위한 class로 CacheEventListener를 구현합니다.
CacheLogger.java
import org.ehcache.event.CacheEvent;
import org.ehcache.event.CacheEventListener;
public class CacheLogger implements CacheEventListener<Object, Object> {
@Override
public void onEvent(CacheEvent<? extends Object, ? extends Object> cacheEvent) {
cacheEvent.getKey();
cacheEvent.getType();
cacheEvent.getSource();
cacheEvent.getOldValue();
cacheEvent.getNewValue();
}
}
onEvent method에서는 현재 성성/만료/삭제되는 캐시의 key value등을 확인 가능합니다.
getSource의 경우 deprecated 되었습니다.
4. 활성화
@EnableCahcing으로 캐시를 활성화 해줍니다.
package com.trandent.config; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Configuration; @Configuration @EnableCaching public class CacheConfig {}
5. 사용
@Cacheable(value = "", key= "") // 캐시 사용
@CacheEvict(value = "", key = "") // key로 캐시 삭제
@CacheEvict(value = "", allEntries = true) // 해당 alias 캐시 전체 삭제
serviceImpl.java
아래와 같이 value만 사용할수도 있고 value + key 조합 기준으로 캐시를 생성할수도 있습니다.
@Override @Cacheable(value = "boardList") public List<Category> getBoardList() { // TODO Auto-generated method stub return categoryMapper.selectBoardList(); }
이 경우 게시판 카테고리별 캐시가 생성됩니다.
@Override @Cacheable(value = "boardList", key="#paramDto.category") public List<Category> getBoardList(ParamDto paramDto) { // TODO Auto-generated method stub return boardMapper.selectBoardList(pramDto); }
여러가지 키를 조합 할 수도 있습니다.
카테고리 + 페이지 별 캐시가 생성됩니다.
@Override @Cacheable(value = "boardList", key="{#paramDto.category, #paramDto.pageNo}") public List<Category> getBoardList(ParamDto paramDto) { // TODO Auto-generated method stub return boardMapper.selectBoardList(pramDto); }
여기서 문제는 캐시가 1시간동안 유지되게 했기 때문에, 그 사이 글을 쓰거나 수정 삭제 하면 반영이 안되게 됩니다.
변동이 생기는 경우 CacheEvict를 사용하여 캐시를 삭제합니다.
@CacheEvict(value = "boardList", key="{#paramDto.category, #paramDto.pageNo}") public int insertBoard(ParamDto paramDto){ //Todo }