general java

Spring-Cache 키 생성 유의사항

'김용환' 2012. 9. 5. 10:08

 

 

Spring Cache Annotation을 쓰던, AOP를 이용해서 Spring Cache를 이용하든

Spring Cache에 대한 default Key 생성 방법을 알아두면 편리하다.

 

만약 Cache로 사용하기 위해서 아래와 같이 코딩을 했다면, Key의 타입은 바로 int 이다.

 

@Cacheable

public String a() {

}

 

그렇다면, 아래와 같이 코딩했다면. Key의 타입은 long 이 된다.

@Cacheable

public String b(long a) {

}

 

만약 파라미터가 String, String 이면, Key의 타입은 int 이다.

@Cacheable

public String b(String b1, String b2) {

}

 

 

Spring Cache 의 Key default 생성 알고리즘은 코드는 아래와 같다.

 

public class DefaultKeyGenerator implements KeyGenerator {

 

public static final int NO_PARAM_KEY = 0;
public static final int NULL_PARAM_KEY = 53;

 

public Object generate(Object target, Method method, Object... params) {
    if (params.length == 1) {
        return (params[0] == null ? NULL_PARAM_KEY : params[0]);
    }
   if (params.length == 0) {
        return NO_PARAM_KEY;
    }
    int hashCode = 17;
    for (Object object : params) {
        hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : object.hashCode());
    }
    return Integer.valueOf(hashCode);
}

}

 

 

만약 long 값의 범위를 가지는 String 값을 캐쉬로 쓰기 위해서는 자칫 잘못하다가는 int로 변환될 수 있는 단점을 가지고 있다. 또한, 파라미터가 없을 때, cache의 혼동이 올 수 있다.

 

따라서,Spring Cache를 하나의 메소드로 단순하게 사용할 것이 아니면, Custom Key Generation을 넣는 코드를 아래와 같이 넣는 것이 아주 좋다. 명확한 키 생성은 디버그에 훨씬 도움이 된다. (특히 Redis를 쓰는 경우에는… 아주 효과적인듯.)

 

사례1)

@Cacheable(value = "cacheName", key = "T(com.google.cache.KeyCreatorBean).createKey(#p0, #p1)")
@Override
public String getName(String id, String class) {
  ...
}

 

 

package com.google.cache.KeyCreatorBean;

public class KeyCreatorBean  {
    public static Object createKey(Object o1, Object o2) {
        return o1 + ":" + o2;
    }
}

 

사례2)

 

<cache:advice id="localRedisCacheAdvice" cache-manager="localRedisCacheManager">
    <cache:caching>
        <cache:cacheable cache="localCache" method="getReceivable" key="T(com.google.cache.KeyCreatorBean).createKey(#p0, #p1)" />
    </cache:caching>
</cache:advice>

 

 

 

package com.google.cache.KeyCreatorBean;

public class KeyCreatorBean  {
    public static Object createKey(Object o1, Object o2) {
        return o1 + ":" + o2;
    }
}

 

 

참고로. Spring Cache AOP에 대한 정보는 org.springframework.cache.interceptor.CacheAspectSupport  클래스를 참조할 필요가 있다.

 

http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.context/3.1.0/org/springframework/cache/interceptor/CacheAspectSupport.java