IT_Programming/Dev Libs & Framework

[Spring] Spring 3.1 + Couchbase 를 이용하여 Cache 만들기

JJun ™ 2015. 7. 9. 00:36



 출처: http://debop.blogspot.kr/2013/03/spring-31-couchbase-cache.html



이번에는 Couchbase 를 저장소로 사용하여, Spring Cache 를 사용해 보도록 하겠습니다.
간략하게 Couchbase 에 대해 설명하면... Memcached + CouchDB 라고 보시면 되구요.
설정에 따라 메모리 저장소로 (Memcached), Document DB 형태(CouchDB) 로 사용할 수 있습니다.

Memcached 의 단순 캐시에서 DocumentDB 로 발전했다고 보시면 되고, Map Reduce 도 가능합니다.

하지만!!! 오늘은 그냥 캐시로 사용하려고 합니다.

1. CouchbaseCacheManager


@Slf4j

public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheManager {
    private CouchbaseClient couchbaseClient;
    @Getter
    @Setter
    private int expireMillis = 0;  // 0 : persist forever
    public CouchbaseCacheManager(CouchbaseClient couchbaseClient) {
        this(couchbaseClient, 0);
    }
    public CouchbaseCacheManager(CouchbaseClient couchbaseClient, int expireMillis) {
        Guard.shouldNotBeNull(couchbaseClient, "couchbaseClient");
        this.couchbaseClient = couchbaseClient;
        this.expireMillis = expireMillis;
    }
    @Override
    protected Collection<? extends Cache> loadCaches() {
        Collection<Cache> caches = Lists.newArrayList();
        for (String name : getCacheNames()) {
            caches.add(new CouchbaseCache(name, couchbaseClient, expireMillis));
        }
        return caches;
    }
    @Override
    public Cache getCache(String name) {
        synchronized (this) {
            Cache cache = super.getCache(name);
            if (cache == null) {
                cache = new CouchbaseCache(name, couchbaseClient, expireMillis);
                addCache(cache);
            }
            return cache;
        }
    }
}



2. CouchbaseCache


@Slf4j

public class CouchbaseCache implements org.springframework.cache.Cache {
    @Getter
    private String name;
    @Getter
    private CouchbaseClient nativeCache = null;
    @Getter
    @Setter
    private int expireMillis = 0; // msec (0 is persist forever)
    public CouchbaseCache(String name, CouchbaseClient client, int expireMillis) {
        Guard.shouldNotBeNull(name, "name");
        Guard.shouldNotBeNull(client, "client");
        this.name = name;
        this.nativeCache = client;
        this.expireMillis = expireMillis;
        if (log.isDebugEnabled())
            log.debug("CouchbaseCache 를 생성합니다. name=[{}], nativeCache=[{}]", name, nativeCache);
    }
    private String getKey(Object key) {
        return name + "|+|" + key;
    }
    @Override
    public ValueWrapper get(Object key) {
        Guard.shouldNotBeNull(key, "key");
        Object result = nativeCache.get(getKey(key));
        SimpleValueWrapper wrapper = null;
        if (result != null)
            wrapper = new SimpleValueWrapper(result);
        return wrapper;
    }
    @Override
    public void put(Object key, Object value) {
        Guard.shouldNotBeNull(key, "key");
        OperationFuture<Boolean> setOp = nativeCache.set(getKey(key), expireMillis, value);
        if (setOp.getStatus().isSuccess()) {
            if (log.isDebugEnabled())
                log.debug("객체를 캐시 키[{}]로 저장했습니다.", key);
        } else {
            if (log.isDebugEnabled())
                log.debug("객체를 캐시 키[{}]로 저장하는데 실패했습니다.. operation=[{}]", key, setOp);
        }
    }
    @Override
    public void evict(Object key) {
        Guard.shouldNotBeNull(key, "key");
        if (log.isDebugEnabled())
            log.debug("delete cache item... key=[{}]", key);
        nativeCache.delete(key.toString());
    }
    @Override
    public void clear() {
        if (log.isDebugEnabled())
            log.debug("clear cache...");
        nativeCache.flush();
    }
}



3. CouchbaseCacheConfiguration


@Configuration

@EnableCaching
@ComponentScan(basePackageClasses = {UserRepository.class})
@Slf4j
public class CouchbaseCacheConfiguration {
    @Bean
    public List<URI> couchbaseList() {
        List<URI> uris = Lists.newArrayList(URI.create("http://localhost:8091/pools"));
        return uris;
    }
    @Bean
    public CouchbaseClient couchbaseClient() throws IOException {
        return new CouchbaseClient(couchbaseList(), "default", "");
    }
    @Bean
    public CouchbaseCacheManager couchbaseCacheManager() throws IOException {
        return new CouchbaseCacheManager(couchbaseClient());
    }
}


환경 설정은 각자 환경에 맞추면 됩니다만, default bucket 만 비밀번호 없이 접근이 가능합니다.
다른 bucket 을 사용하려면, 미리 만드시고, 보안을 설정하셔야 합니다.



4. Couchbase Admin Screenshot