스프링에서 캐싱기능을 사용해봅니다.
어노테이션을 이용한 캐싱 기능을 사용해봅니다.
Goal
@EnableCaching
+@Cacheable
를 이용해 캐시를 적용하는법을 알아봅니다.@CachePut
을 이용해 캐시를 업데이트 해봅니다.@CacheEvit
을 이용해 캐시를 삭제하는 방법을 알아봅니다.- 스케쥴링 옵션을 넣어서 작동으로 삭제도 해봅니다.
캐싱 설정
@EnableCaching
을 이용해 캐싱기능 활성화, 함수에@Cacheable
을 이용해 캐싱 타겟 설정
1 |
|
@EnableCaching
를 어플리케이션 or 캐싱설정에 붙여줍니다.- ChacheManager 를 직접 다루는 방법은 이글에서 설명하지 않습니다. (추후 다른글에서 설명할 수도 있습니다.)
1 |
|
캐싱 관련 어노테이션은 AOP + Proxy 기반 으로 작동하기 때문에, 내부 호출(Self invocation)을 하는경우에는 작동하지 않습니다.
- 어느 캐시에 저장할것인지 (
value
orcacheNames
), 어떤것을 기준으로 캐싱할것인지 (key
)를 정해 줄 수 있습니다. - key를 명시해주지 않으면, 파라메터의 모든 값이 key가 됩니다.
- 여러개의 파라메터를 하나의 key 값으로 묶고 싶은경우에는
+
를 이용해 주면 됩니다. - 객체 형식의 파라메터를 받는 경우에도
#req.name
과 같은 형식으로 객체내 필드값으로 키값을 정해줄 수 있습니다.
1 |
|
- 클래스내 모든 메서드에서 같은 캐시테이블을 사용할 예정이면
@CacheConfig
를 이용해 전역적으로 옵션을 줄수도 있습니다.
캐시 업데이트
@CachePut
을 이용합니다.
1 |
|
- 캐시에 들어가있는 정보를 업데이트 하고 싶은 경우가 있을 수 있습니다.
- 이경우에는
@CachePut
을 이용하고, value에 업데이트 하고 싶은 캐시테이블 이름을 넣어주면 됩니다. - 또한, condition 과 같은 옵션을 넣어서, 캐싱에 필요한 조건식을 같이 넣어줄 수 있습니다.
객체를 기반으로 한 캐싱
1 |
|
- 객체를 그대로 캐싱하는 경우, 해시코드 값을 기반으로 캐싱을 진행하게 됩니다.
1 |
|
- 따라서 데이터를 동일하게 담고 있어도, 구현이 되어있지 않다면, 캐싱된 결과를 반환하지 않게 됩니다.
- 객체 기반으로 캐싱을 원하는 경우,
equals()
,hashCode()
를 Request 에 구현 해주거나, kotlin 의 경우에는 data class 를 사용하시면 되겠습니다.
파라메터가 없는 경우를 캐싱하는방법
1 |
|
- 종종 key 값이 마땅한것이 없지만, 캐싱한 결과를 내보내고 싶을 수 있습니다.
- 이 경우에는
key = "#root.method.name"
or#root.methodName
처럼 메서드 이름을 key 값으로 잡고, 처리해주면 됩니다.
캐싱 조건
condition
특정 조건일 경우 캐싱
1 |
|
condition
을 통해서 캐싱 조건을 줄 수 있습니다.- 함수를 이용해서도 조건절 처리가 가능합니다.
unless
캐싱되지 않을 조건
1 |
|
- 특정 조건의 경우, 캐싱을 원하지 않는다면
unless
를 이용해 구분이 가능합니다. - 주의할점은 조건으로
Enum
을 주는 경우,SpEL
을 통해 해석하지못해 에러가 발생하게 됩니다. - 해당 경우에는
req.isNeedCache()
와 같이 조건문으로 풀어서 해결할 수 있습니다. - 또한
SpEL
은 기본적으로 자바 문법을 기반으로 해석할 수 있으므로, kotlin 에서만 제공하는 문법은 사용할 수 없습니다. - 다만 어느정도는 지원이 되는지
req.name.length()
=>req.name.length
정도는 해석하고 있습니다. 이부분은SpEL
을 좀더 파보아야겠습니다.2023-02-08
캐시 삭제
@CacheEvict
을 이용합니다.
1 |
|
- 캐싱 기능인
@Cacheable
와 완전히 똑같이 옵션을 주면 됩니다. - 해당 메서드가 호출되는 경우,
name
에 적용되어있던 캐싱 정보가 삭제됩니다.
캐싱 주기적 삭제
@Scheduled
를 이용합니다.
1 |
|
Evict
을 주기적으로 호출할 수 있도록@Scheduled
를 이용해주면됩니다.@Scheduled
가 붙은 메서드는 파라메터를 가지면 안되고, public 해야한다는것에 주의해야합니다.- 예제의 경우
allEntries = true
옵션을 통해cacheTest3
캐시에 담겨있던 정보를 1초 간격으로 전부 삭제하게 됩니다.
번외
Conclusion
- 캐싱 관련 어노테이션들(
@EnableCaching, @Cacheable, @CachePut, @CacheEvict
)을 이용해, 스프링에서 쉽게 캐싱 등록, 수정, 삭제를 구현할 수 있다. - 관련된 코드는 github 에서 볼 수 있습니다.
Reference
- https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/cache.html
- https://www.baeldung.com/spring-cache-tutorial
- https://stackoverflow.com/questions/8181768/can-i-set-a-ttl-for-cacheable
- https://www.baeldung.com/spring-boot-evict-cache
- https://stackoverflow.com/questions/48888760/cachable-on-methods-without-input-parameters