라이브러리

KeyGenerator을 활용한 Spring Cache key 생성하기

탄생 2022. 6. 15. 17:46

● 개요

캐시를 활용하여 데이터를 저장할때 로그인사용자, 메소드, 파라미터값등 다양한 필드별로 유니크한 key를 조합하여 데이터를 저장해야 하는 경우 cache key를 한곳에서 생성 관리해주고자 한다.

spring cache의 활용편으로spring cache 적용은 이곳(https://myborn.tistory.com/24) 을 참고해 주세요.


● Custom KeyGenerator를 활용하기

1. Custom KeyGenerator 생성

- KeyGenerator 를 상속받아 구현합니다.

target - instance,
mehtod - 호출 메소드,
params - 호출 메소드의 파라미터 인자입니다.

생성된 키값을 리턴하여 캐시의 key로 사용됩니다.

import java.lang.reflect.Method;

import org.springframework.cache.interceptor.KeyGenerator;

import com.wisebirds.lguplus.backend.util.SessionUtils;

public class CacheKeyGenerator implements KeyGenerator {

    @Override
    public Object generate(Object target, Method method, Object... params) {
        return String.format("%s-%s-%s-%s", SessionUtils.getId(),
                             target.getClass().getSimpleName(),
                             method.getName(),
                             arrayToDelimitedString(params));
    }

    public String arrayToDelimitedString(Object... params) {
        final var sb = new StringBuilder();
        for (var i = 0; i < params.length; i++) {
            sb.append(params[i].hashCode());
            if (i != params.length - 1) {
                sb.append("-");
            }
        }
        return sb.toString();
    }
}

※ 주의사항

파라미터를 dto(object)로 구현시 모든 파라미터를 연결하면 key가 길어지기 때문에 hashCode를 활용하여 동일한 object여부를 비교하였습니다. dto의 값이 동일한지 확인할 수 있도록 @EqualsAndHashCode 를 정의해 주셔야 합니다. 

    @Setter
    @Getter
    @Builder
    @EqualsAndHashCode
    @NoArgsConstructor
    @AllArgsConstructor
    class Request {
    	private String name;
        
        private String field;
        
        private String field2
    }

2.  생성한 KeyGenerator를 빈에 등록해줍니다.

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.wisebirds.lguplus.backend.component.CacheKeyGenerator;

@EnableCaching
@Configuration
public class CacheConfig {

    @Bean("cacheKeyGenerator")
    public KeyGenerator keyGenerator() {
        return new CacheKeyGenerator();
    }
}

3. 생성한 KeyGenerator를 @Cacheable에 적용

@Cacheable(cacheNames = "cacheStore", keyGenerator = "cacheKeyGenerator")
public String getCache(String name) throws InterruptedException {
    sleep(3000);
    return name;
}

참고 url

https://ckddn9496.tistory.com/110
https://www.baeldung.com/spring-cache-custom-keygenerator