2017년 2월 22일 수요일

SpringBoot Data Cache 적용하기

Springboot + Spring data cache를 적용하는 방법이다.
적용 할 때 특정 cache는 ttl을 별도 지정하고 key(String)를 눈으로 확인 할 수 있도록 String 형태로 구성한다.

일단 Configuration을 작성하고..
(cache ttl을 별도 옵션으로 뺐기 때문에 CacheExpireProperties class를 이용해서 yml의 properties를 load한다)


@EnableCaching
@AutoConfigureAfter(CacheAutoConfiguration.class)
@Configuration
public class CacheConfiguration extends CachingConfigurerSupport {
    @Autowired
    private CacheExpireProperties cacheExpireProperties;

    @Override
    public KeyGenerator keyGenerator() {
        return new CustomKeyGenerator();
    }

    @Override
    public CacheErrorHandler errorHandler() {
        return new CustomCacheErrorHandler();
    }

    @Bean
    @Primary
    public RedisTemplate redisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(new GenericToStringSerializer(String.class));

        return template;
    }


    @Bean
    public CacheManagerCustomizer cacheManagerCustomizers() {
        return (CacheManagerCustomizer) cacheManager -> {
            cacheManager.setExpires(cacheExpireProperties.getExpires());
        };
    }

}
cache에 key로 쓸 keyGenerator를 만들자

public class CustomKeyGenerator implements KeyGenerator{

    private static final String delimiter = ":";

    @Override
    public Object generate(Object target, Method method, Object... params) {
        return generate(params);
    }

    public Object generate(Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append("sample");
        if(Objects.nonNull(params) && params.length > 0){
            sb.append(delimiter);

            for(int i = 0; i < params.length ; i++){
                sb.append(params[i].toString());

                if(i < params.length - 1)
                    sb.append(delimiter);
            }
        }

        return sb.toString();
    }
}
cache를 처리하다가 exception이 난 경우 이를 처리 하는 Handler도 만들자

public class CustomCacheErrorHandler implements CacheErrorHandler{
    @Override
    public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
        log.error("cache not get");
    }

    @Override
    public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
        throw exception;
    }

    @Override
    public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
        throw exception;
    }

    @Override
    public void handleCacheClearError(RuntimeException exception, Cache cache) {
        throw exception;
    }
}
ttl을 별도 적용 할 cacheName 및 설정값을 읽자

@Data
@Component
@ConfigurationProperties(prefix = CacheExpireProperties.PREFIX)
public class CacheExpireProperties {
    public static final String PREFIX = "sample.cache";

    private Map expires = new HashMap<>();
}
application.yml에 아래처럼 설정하자

sample:
  cache:
    expires:
      foods: 300
간단히 어노테이션만 달면.. 완성!

    @Cacheable("foods")
    public Food findFood(long storeId, long foodId){
       ...
    }

댓글 없음:

댓글 쓰기