1. Setup CacheConfiguration
2. Extend AbstractCacheManager
3. Implement Cache
4. Implement CachingConfigurer
1. Setup CacheConfiguration
package com.example.cache;
import java.io.IOException;
import java.net.URISyntaxException;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactory;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CacheConfiguration {
@Bean
public MemcachedClient memcachedCloudConfiguration() {
try {
AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" },
new PlainCallbackHandler(System.getenv("MEMCACHEDCLOUD_USERNAME"), System.getenv("MEMCACHEDCLOUD_PASSWORD")));
MemcachedClient mc = new MemcachedClient(
new ConnectionFactoryBuilder()
.setTranscoder(new CustomSerializingTranscoder())
.setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
.setAuthDescriptor(ad).build(),
AddrUtil.getAddresses(System.getenv("MEMCACHEDCLOUD_SERVERS")));
return mc;
} catch (IOException ex) {
// the Memcached client could not be initialized.
}
return null;
}
}
2. Extend AbstractCacheManager
package com.example.cache;
import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractCacheManager;
import org.springframework.util.Assert;
import java.util.Collection;
/**
* Created by tmichels on 3/19/15.
*/
public class MemCacheManager extends AbstractCacheManager {
private final Collection<MemCache> internalCaches;
public MemCacheManager(final Collection<MemCache> internalCaches) {
this.internalCaches = internalCaches;
}
@Override
protected Collection<? extends Cache> loadCaches() {
Assert.notNull(internalCaches, "A collection caches is required and cannot be empty");
return internalCaches;
}
}
3. Implement Cache
package com.example.cache;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.transcoders.SerializingTranscoder;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* Created by tmichels on 3/19/15.
*/
public class MemCache implements Cache {
@Autowired
MemcachedClient cache;
private final String name = "";
private static final Logger LOGGER = Logger.getLogger(MemCache.class);
@Override
public String getName() {
return name;
}
@Override
public Object getNativeCache() {
return cache;
}
@Override
public ValueWrapper get(final Object key) {
Object value = null;
try {
value = cache.get(key.toString());
} catch (final Exception e) {
LOGGER.warn(e);
}
if (value == null) {
return null;
}
return new SimpleValueWrapper(value);
}
@Override
public void put(final Object key, final Object value) {
cache.set(key.toString(), 7 * 24 * 3600, value);
Assert.assertNotNull(get(key)); //This fails on the viewCache
}
@Override
public void evict(final Object key) {
this.cache.delete(key.toString());
}
@Override
public void clear() {
cache.flush();
}
}
4. Implement CachingConfigurer
package com.example.cache;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.interceptor.DefaultKeyGenerator;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class SimpleCacheConfiguration implements CachingConfigurer {
@Override
@Bean
public CacheManager cacheManager() {
CacheManager cacheManager;
try {
cacheManager = new MemCacheManager(internalCaches());
return cacheManager;
} catch (final URISyntaxException e) {
throw new RuntimeException(e);
}
}
@Bean
public Collection<MemCache> internalCaches() throws URISyntaxException {
final Collection<MemCache> caches = new ArrayList<MemCache>();
caches.add(new MemCache());
return caches;
}
@Override
public KeyGenerator keyGenerator() {
return new DefaultKeyGenerator();
}
}
Hi,
Thank you very much for your blog. It is very helpful.
I have only one query, will you please let me know after adding all these configuration files for spring Memcached. can we use spring cache annotations like @Cachable, @CachePut so on?
One more thing I would like to ask regarding,
In MemCache.java class you have mentioned name variable which is cache name, so how spring boot application will get this name dynamically. eg. @Cacheable(“any-name”)
Will you please help me to understand this. Thank you very much in advance for your valuable time.