- 메서드 레벨의 캐시를 적용할때 붙이는 어노테이션
- 메서드의 인자를 기반으로 key 를 만들어서 똑같은 메서드 인자로 호출하면 이전에 호출되었던 값을 반환함
- 사용하기 위해서는
spring-boot-starter-cache
의존성 추가해야함
스프링 어플리케이션에@EanbleCaching
어노테이션 추가
@SpringBootApplication @EnableFeignClients @EnableCaching public class VirtualofficeApplication { public static void main(String[] args) { SpringApplication.run(VirtualofficeApplication.class, args); } }
- 별다른 Provider 설정 해주지 않으면 인메모리에서 ConcurrentHashMap 만들어서 캐시 관리하고 yaml 설정해주면 Provider 설정도 쉽게 가능함
- EhCache, Hazelcast, Redis, and others
spring: cache: type: SIMPLE # ConcurrentMapCache # REDIS # NONE NoOpCache. 캐시 사용안함
@Cacheable(cacheNames="books", key="#isbn", cacheManager="anotherCacheManager") public Book getByIsbn(String isbn, boolean checkWarehouse, boolean includeUsed)
CacheManager 설정
@Bean fun cacheManager(lettuceConnectionFactory: LettuceConnectionFactory): RedisCacheManager { val configuration = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith( RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer())) .serializeValuesWith( RedisSerializationContext.SerializationPair.fromSerializer(GenericJackson2JsonRedisSerializer(), ), ) .disableCachingNullValues()
Serializer/Deserializer에 관한 내용은 Spring Data Redis 페이지 참고
TroubleShooting
- redis 설정이 되어있기만 하면 자동으로 RedisCache를 사용하게 됨
- 별다른 설정 안해서 ConcurrentMapCache 사용할 줄 알았는데 아니었음. Redis 설정만 되어 있으면 RedisCache 사용함
나는 해당 어노테이션을 객체를 다시 만들지 않기 위해서 사용했는데 RedisCache를 쓰면 내부적으로 Cache.ValueWrapper 라는 것을 이용하기에 객체를 계속 새로 만들어서 반환해 줌 ⇒ 큰 의미 없다..

@Cacheable(cacheNames = "gameServerUrl", key="#channelServerHost") public URI baseUrl(String channelServerHost) { System.out.println("aaa"); return URI.create(String.format("http://%s:%d", channelServerHost, gameServerPort)); }
- ConcurrentMapCache 사용하니까 인스턴스 새로 생성안함! (당연하게도)