Amol Potnis
Amol Potnis

Reputation: 93

Unable to get good example of using memcached from Java boot

I am using java boot for my development. For now I have used 'EhCache' for caching , it is directly supported from Java boot. This is "in-process" cache, i.e., becomes part of your process. It is okay for now. But my server will run on multiple nodes in near future. Hence want to switch to 'Memcached' as common caching layer.

After spending good amount of time, I could not get good sample of using Memcached from java boot. I have looked at 'Simple Spring Memcached' which comes close to my requirement. But still it gives example using XML configuration in Spring way. Java boot does not use such XML configuration as far as possible. At least I could not map the example quickly to java boot world.

I want to use Memcahed ( directly or via cache-abstraction-layer) from java boot. If anybody points me to a relevant java boot example, it will save a lot of time for me.

Upvotes: 1

Views: 3116

Answers (3)

Saša
Saša

Reputation: 663

You could also check Memcached Spring Boot library. It uses Memcached implementation for Spring Cache Abstraction.

In other words you use the same configuration and same annotations as you would use with any other Spring Cache implementation. You can check out here the usage of the library.

There are also example projects in Kotlin and Java.

Upvotes: 2

Amol Potnis
Amol Potnis

Reputation: 93

I have already accepted answer given by @ragnor. But I think I should post a complete example here which has worked for me.

  1. Make sure you have cache-enabled for your application by adding @EnableCaching
  2. POM.xml should have following dependency:
<dependency>
        <groupId>com.google.code.simple-spring-memcached</groupId>
        <artifactId>spring-cache</artifactId>
        <version>3.6.1</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.simple-spring-memcached</groupId>
        <artifactId>spymemcached-provider</artifactId>
        <version>3.6.1</version>
    </dependency>
  1. Add a config file to configure your memcached cache configuration, say MySSMConfig.java
@Configuration
@EnableAspectJAutoProxy
@ImportResource("simplesm-context.xml") // This line may or may not be needed,
                                        // not sure
public class SSMConfig 
{
    private String _memcachedHost; //Machine where memcached is running
    private int _memcachedPort;    //Port on which memcached is running

     @Bean
     public CacheManager cacheManager() 
     {
         //Extended manager used as it will give custom-expiry value facility in future if needed
         ExtendedSSMCacheManager ssmCacheManager = new ExtendedSSMCacheManager();

         //We can create more than one cache, hence list
         List<SSMCache>cacheList = new ArrayList<SSMCache>();

         //First cache: Testcache
         SSMCache testCache = createNewCache(_memcachedHost, _memcachedPort, 
                                    "testcache", 5);

         //One more dummy cache
         SSMCache dummyCache = createNewCache(_memcachedHost,_memcachedPort, 
                    "dummycache", 300);

         cacheList.add(testCache);
         cacheList.add(dummyCache);

         //Adding cache list to cache manager
         ssmCacheManager.setCaches(cacheList);

         return ssmCacheManager;
     }


    //expiryTimeInSeconds: time(in seconds) after which a given element will expire
    //
    private SSMCache createNewCache(String memcachedServer, int port, 
                                String cacheName, int expiryTimeInSeconds)
    {
        //Basic client factory to be used. This is SpyMemcached for now.
        MemcacheClientFactoryImpl cacheClientFactory = new MemcacheClientFactoryImpl();

        //Memcached server address parameters
        //"127.0.0.1:11211"
        String serverAddressStr = memcachedServer + ":" + String.valueOf(port);
        AddressProvider addressProvider = new DefaultAddressProvider(serverAddressStr);

        //Basic configuration object
        CacheConfiguration cacheConfigToUse = getNewCacheConfiguration();

        //Create cache factory
        CacheFactory cacheFactory = new CacheFactory();
        cacheFactory.setCacheName(cacheName);
        cacheFactory.setCacheClientFactory(cacheClientFactory);
        cacheFactory.setAddressProvider(addressProvider);
        cacheFactory.setConfiguration(cacheConfigToUse);

        //Get Cache object
        Cache object = null;
        try {
            object = cacheFactory.getObject();
        } catch (Exception e) {

        }

        //allow/disallow remove all entries from this cache!!
        boolean allowClearFlag = false;
        SSMCache ssmCache = new SSMCache(object, expiryTimeInSeconds, allowClearFlag); 

        return ssmCache;

    }

    private CacheConfiguration getNewCacheConfiguration() 
    {
        CacheConfiguration ssmCacheConfiguration = new CacheConfiguration();
        ssmCacheConfiguration.setConsistentHashing(true);
        //ssmCacheConfiguration.setUseBinaryProtocol(true);
        return ssmCacheConfiguration;
    }

}
  1. OK, we are ready to use our configured cache.
  2. Sample methods in some other class to read from cache and to remove from cache
@Cacheable(value="dummycache, key="#givenId.concat('-dmy')", unless="#result == null")
    public String getDummyDataFromMemCached(String givenId)
    {
        logger.warn("getDummyDataFromMemCached: Inside DUMMY method to actually get data");
        return "Sample-" + String.valueOf(givenId);
    }
    @CacheEvict(value="dummycache",key="#givenId.concat('-dmy')")
    public void removeDummyDataFromMemCached(String givenId)
    {
        //Do nothing
        return;
    }
  1. Note that we have added suffix to the kache-keys. As Memcached does not support cache-zones, "dummycache" and "testcache" ultimately does not remain separate on a single server. (They may remain separate with some other cache implementation). Hence to avoid conflict, we append unique suffix to the cache-key.

  2. If you want to cache objects of your own class, then make sure that they are serializable. Just change your class definition to 'XYZ implements Serializable'.

Upvotes: 1

ragnor
ragnor

Reputation: 2528

You can find some materials how to configure SSM using Java configuration instead of XML files here and here. Basically you have to move definitions of all beans from XML to Java.

Upvotes: 0

Related Questions