2017-01-05 8 views
7

मैं @Cacheable के भीतर कैश कुंजी (ओं) को परिभाषित सर्वर पक्ष पर स्प्रिंग कैशिंग (EHCache के साथ) का उपयोग कर रहा हूं। समस्या यह है कि विभिन्न ग्राहक एक ही तार भेजते हैं जो विभिन्न वर्तनी वाले कुंजियों के रूप में उपयोग किए जाते हैं क्योंकि वे इसे केस संवेदनशील भेजते हैं। नतीजा यह है कि मेरे कैश में अधिक ऑब्जेक्ट्स होते हैं जो उन्हें करना होगा।वसंत कैश में केस संवेदनशील कुंजी से कैसे बचें?

उदाहरण: चलो कहते हैं कि मैं निम्नलिखित कैशिंग एक निश्चित विधि के लिए परिभाषित किया है दो:

@Cacheable(value = "myCache", key="{#myString}") 
public SomeBusinessObject getFoo(String myString, int foo){ 
... 
} 

अब ग्राहक एक नियंत्रक के लिए "abc" (सभी लोअरकेस) भेजता है। नियंत्रक कॉल getFoo और "abc" को ऑब्जेक्ट को कैश में रखने के लिए कुंजी के रूप में उपयोग किया जाता है। क्लाइंट बी "एबीसी" (अपरकेस सी) भेजता है और कुंजी "एबीसी" के लिए कैश किए गए ऑब्जेक्ट को वापस करने के बजाय कुंजी "एबीसी" के लिए एक नया कैश ऑब्जेक्ट बनाया जाता है।

मैं केस संवेदनशील होने के लिए कुंजी से कैसे बच सकता हूं?

मैं जानता हूँ कि मैं निर्धारित कर सकते हैं कैश कुंजी इस तरह लोअरकेस जा करने के लिए:

@Cacheable(value = "myCache", key="{#myString.toLowerCase()}") 
public SomeBusinessObject getFoo(String myString, int foo){ 
... 
} 

इस कोर्स काम करने की है। लेकिन मैं एक और सामान्य समाधान की तलाश में हूं। मेरे पास कई कैश और कई कैश कुंजी हैं और कुछ @CacheEvict (s) और @CachePut (ओं) करते हैं और यदि मैं उस "toLowerCase" दृष्टिकोण का उपयोग करता हूं तो मुझे हमेशा यह सुनिश्चित करना होगा कि इसे कहीं भी न भूलें।

+0

हो सकता है कि यह उपयोगी है, है अपनी खुद की Keygenerator http://stackoverflow.com/questions/27574786/generating-unique-cache-key-with-spring-keygenerator-not-working – gaston

+0

मुझे लगता है कि आप कर सकते हैं प्रतिनिधि वास्तविक कैशिंग को कार्यान्वित करने के लिए एक और विधि * * के बाद * आप कुंजी में वांछित संशोधन करते हैं –

उत्तर

0

जैसा कि @ गैस्टन ने उल्लेख किया है, समाधान डिफ़ॉल्ट KeyGenerator को बदल रहा है। आपके Configuration में org.springframework.cache.annotation.CachingConfigurer लागू करना या org.springframework.cache.annotation.CachingConfigurerSupport का विस्तार करना।

@Configuration 
@EnableCaching 
public class AppConfig extends CachingConfigurerSupport { 
    @Override 
    public KeyGenerator keyGenerator() { 
     return new MyKeyGenerator(); 
    } 

    @Bean 
    @Override 
    public CacheManager cacheManager() { 
     //replaced with prefered CacheManager... 
     SimpleCacheManager cacheManager = new SimpleCacheManager(); 
     cacheManager.addCaches(Arrays.asList(new ConcurrentMapCache("default"))); 
     return cacheManager; 
    } 
} 

यहां एक कार्यान्वयन org.springframework.cache.interceptor.SimpleKeyGenerator से संशोधित किया गया है।

import java.lang.reflect.Method; 
import org.springframework.cache.interceptor.KeyGenerator; 
import org.springframework.cache.interceptor.SimpleKey; 

public class MyKeyGenerator implements KeyGenerator { 

    @Override 
    public Object generate(Object target, Method method, Object... params) { 
     if (params.length == 0) { 
      return SimpleKey.EMPTY; 
     } 
     if (params.length == 1) { 
      Object param = params[0]; 
      if (param != null) { 
       if (param.getClass().isArray()) { 
        return new MySimpleKey((Object[])param); 
       } else { 
        if (param instanceof String) { 
         return ((String)param).toLowerCase(); 
        } 
        return param; 
       } 
      } 
     } 
     return new MySimpleKey(params); 
    } 
} 

मूल कार्यान्वयन SimpleKey वर्ग का उपयोग करते समय @Cacheable विधि एक से अधिक तर्क है कुंजी का उत्पादन। केस असंवेदनशील कुंजी बनाने के लिए यहां एक और कार्यान्वयन है।

import java.io.Serializable; 
import java.util.Arrays; 
import org.springframework.util.Assert; 
import org.springframework.util.StringUtils; 
@SuppressWarnings("serial") 
public class MySimpleKey implements Serializable { 
    private final Object[] params; 
    private final int hashCode; 

    /** 
    * Create a new {@link SimpleKey} instance. 
    * @param elements the elements of the key 
    */ 
    public MySimpleKey(Object... elements) { 
     Assert.notNull(elements, "Elements must not be null"); 
     Object[] lceles = new Object[elements.length]; 
     this.params = lceles; 
     System.arraycopy(elements, 0, this.params, 0, elements.length); 
     for (int i = 0; i < elements.length; i++) { 
      Object o = elements[i]; 
      if (o instanceof String) { 
       lceles[i] = ((String)o).toLowerCase(); 
      } else { 
       lceles[i] = o; 
      } 
     } 
     this.hashCode = Arrays.deepHashCode(lceles); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return (this == obj || (obj instanceof MySimpleKey 
       && Arrays.deepEquals(this.params, ((MySimpleKey) obj).params))); 
    } 

    @Override 
    public final int hashCode() { 
     return this.hashCode; 
    } 

    @Override 
    public String toString() { 
     return getClass().getSimpleName() + " [" + StringUtils.arrayToCommaDelimitedString(this.params) + "]"; 
    } 
} 
संबंधित मुद्दे