Search code examples
javaspringcachingspring-cache

Is it possible to define more KeyGenerator classes for cache in Spring version 3.1.x?


I have a configuration class which implements CachingConfigurer to define a cache manager with a specific key generator, but I should use different key generators per caches.

There is an option form Spring 4.1 to specify a key generator per operation:

@Cacheable(cacheNames="cacheName1", keyGenerator="myKeyGenerator1") 
@Cacheable(cacheNames="cacheName2", keyGenerator="myKeyGenerator2") 

I'm wondering if there is any alternative for this in Spring 3.1?


Solution

  • Yes, there is an alternative. The KeyGenerator gives you access to the Method being invoked so you could create a composite of your own kind and redirect accordingly. Here's a pseudo code that would do that:

    @MyKeyGenerator("myKeyGenerator1")
    @Cacheable(cacheNames="cacheName1")
    Foo method1(...) { ... }
    
    @MyKeyGenerator("myKeyGenerator2")
    @Cacheable(cacheNames="cacheName2")
    Bar method2(...) { ... }
    

    MyKeyGeneratoris an annotation of yours. Then you can create a single keyGenerator that looks like this:

    public class MyKeyGenerator extends DefaultKeyGenerator {
    
        @Override
        public Object generate(Object target, Method method, 
                Object... params) {
    
            MyKeyGenerator myKeyGenerator = 
                method.getAnnotation(MyKeyGenerator.class);
            if (myKeyGenerator != null) {
                // read your annotation and invoke the proper
                // key generator according to the value
            } else {
                super.generate(target, method, params);
            }
        }
    }
    

    You can use CachingConfigurer to specify MyKeyGenerator instead of the default.

    Note: an update to Spring Framework 4 is probably in order anyway and you'd benefit from tons of other nice features. Just saying.