@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;
        }
    }
}