프로그래밍/Spring Framework

@Cacheable, @CacheEvict

모지사바하 2013. 5. 9. 15:41

빈번하게 호출돼서 화면에 출력돼야 하는 데이터는 Caching 을 이용하면,

 

속도가 훨씬 빨라진다..

 

아주 간단히 말해, 매번 똑같은 데이터를 굳이 새롭게 호출해야 할 필요 없이

특정 영역에 저장해뒀다가 바로 꺼내쓰는 것이 바로 Caching이다.

 

스프링에선 역시 Caching을 아주 멋들어지 제공한다.

 

캐싱 기능을 적용하고 싶은 메소드에 @Cacheable 에노테이션만 붙여주면 이 메소드는 캐싱기능이 적용된다..

 

@Cacheable 은 여러모로 @Transactional 과 흡사하다..

 

Manager를 등록해야하는것 마저 동일하다 @Transactional 이 transactionManager를 등록해야하는것과 마찬가지로 @Cacheable 은 cacheManager를 등록해야한다..

 

@Cacheable 이나 @Transactional 이 적용되면 이 객체는 proxy 로 감싸져서 부가기능이 추가된다.

 

* 스프링에 proxy-target-class 를 하지 않았고 interface 를 구현한 service라면 죄다.. proxy가 target 을 감싸고 마치 자신이 target 인 양 행동한다.. 이렇게 해야만 AOP를 통해 부가기능을 추가할 때 끼어들 자리가 생긴다..

 

 

@Cacheable 을 적용하면서  내가 직면한 문제는 바로 @CacheEvict 이다.

 

@Cacheable 로 캐싱된 데이터는 반드시 적절한 시점에 제거 되어야한다. 왜냐하면,

 

예를 들어 공지사항을 캐싱해놓고 캐싱된 공지사항 목록을 불러들이는데 새로운 공지사항이 등록됐을 경우,

 

캐싱된 데이터를 계속 불러온다면 새로 등록된 공지사항이 나타나지 않을것이다.. 새로운 공지사항이 등록되는 시점에, 캐싱된 데이터를 제거해줄 필요가 있다.

 

그리고 다시 조회하면 캐싱된 데이터가 없으니 새롭게 공지사항을 조회함과 동시에 캐싱할테고 두번째부턴 새롭게 캐싱된 데이터를 불러올것이다.

 

헌데, @Cacheable 속성에는 value라는 필수 속성을 지정해야하고, key 라는 선택속성을 지정해줄 수가 있다.

하나의 캐시에는 여러가지 데이터가 들어갈 수 있으며, 각 데이터는 키 값이 존재한다.

 key 를 따로 지정해주지 않으면 메소드의 파라미터 변수명이 키 값이 된다. 파라미터가 없다면 0 이 키 값이 된다.

 

@Override
 @StopWatchLogging
 @Transactional(readOnly=true)
 @Cacheable(value = "fileDomain")
 public List<FileDomain> getFileList() {
    return fileMapper.getFileList();
 }

 

이 메소드에서 캐싱을 했고,

@Override
 @CacheEvict(value="fileDomain")
 public void addFile(FileDomain fileDomain){
  try{
   fileMapper.addFile(fileDomain);   
  }catch(FileUploadFailException uploadFailEx){
   logger.error("fileUpload Fail");
   throw new FileUploadFailException(uploadFailEx);   
  }
 }

이 메소드에서 제거를 했으나,,,,

 

제가가 되지 않았다.... 왜 제거가 되지 않았는지는 위 설명에 있지만, 그래도 설명을 하자면 @Cacheable 한 시점에는, 메소드 파라미터가 없기때문에 fileDomain 캐시의 키값이 0 이다..

 

헌데 @CacheEvict 할 때는 파라미터가 있기 때문에 fileDomain 의 fileDomain 키를 찾아 삭제하려는데 fileDomain 이라는 키를 가진 데이터가 없기 때문에 삭제를 할 수가 없다..

 

하여,,,

 

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

allEntries 속성은 해당 캐시의 모든 속성을 뜻한다..

 

위처럼 하거나

 

@CacheEvict(value="fileDomain", key="0")

 

처럼 하여 삭제할 수 있다.