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.