2012-08-24 15 views
35

में शून्य मान को कैश न करें, क्या यह निर्दिष्ट करने का कोई तरीका है कि यदि विधि शून्य मान देता है, तो इस तरह की विधि के लिए परिणाम को कैशबल एनोटेशन में कैश न करें?मैं स्प्रिंग कैश को कैसे बता सकता हूं कि @ कैशेबल एनोटेशन

@Cacheable(value="defaultCache", key="#pk") 
public Person findPerson(int pk) { 
    return getSession.getPerson(pk); 
} 

अद्यतन: यहाँ है JIRA कैशिंग शून्य मान पिछले नवंबर, जो अभी तक हल नहीं किया के बारे में प्रस्तुत मुद्दा: [#SPR-8871] @Cachable condition should allow referencing return value - Spring Projects Issue Tracker

+0

हाय, मुझे लगता है कि आपको टेक ट्रिप का उत्तर स्वीकार्य माना जाना चाहिए, क्योंकि यह वसंत के वर्तमान संस्करण के लिए अधिक प्रासंगिक है। –

उत्तर

59

हुर्रे, स्प्रिंग 3.2 ढांचे के रूप में इस का उपयोग कर स्प्रिंग एसपीईएल और unless के लिए अनुमति देता है। संचित करने योग्य आसपास जावा दस्तावेज़ से ध्यान दें:

http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/cache/annotation/Cacheable.html

सार्वजनिक सार स्ट्रिंग जब तक

स्प्रिंग अभिव्यक्ति भाषा (स्पेल) विशेषता विधि कैशिंग वीटो का इस्तेमाल किया।

स्थिति() के विपरीत, इस अभिव्यक्ति का मूल्यांकन विधि के बाद किया जाता है और इसलिए परिणाम का संदर्भ ले सकता है। डिफ़ॉल्ट "" है, जिसका अर्थ है कि कैशिंग कभी भी vetoed नहीं है।

महत्वपूर्ण पहलू यह है कि unless के बाद विधि बुलाया गया है मूल्यांकन किया जाता है है। यह सही समझ में आता है क्योंकि यदि कुंजी पहले से ही कैश में है तो विधि कभी निष्पादित नहीं होगी।

@Cacheable(value="defaultCache", key="#pk", unless="#result == null") 
public Person findPerson(int pk) { 
    return getSession.getPerson(pk); 
} 

मैं कल्पना कर सकते हैं इस हालत प्लगेबल कैश कार्यान्वयन के उपयोग से उत्पन्न होती है:

इसलिए उपरोक्त उदाहरण में आप बस के रूप में इस व्याख्या होगा (#result एक विधि के रिटर्न मान परीक्षण करने के लिए उपलब्ध है) जैसे कि एशैच जो नल के कैशिंग को अनुमति देता है। आपके उपयोग के मामले परिदृश्य के आधार पर यह वांछनीय हो सकता है या नहीं भी हो सकता है।

+0

हाय, मेरे पास एक परिदृश्य है, जिसमें रेडिस कैशिंग सर्वर अपवादों को कैश करता है। मुझे सर्वर के अपवादों को कैशिंग से बचाना है। क्या मैं इसके लिए "जब तक" पैरामीटर का उपयोग कर सकता हूं? क्या अपवादों का उल्लेख करना संभव है? कृपया अपने सुझाव साझा करें।अग्रिम धन्यवाद – nijogeorgep

+0

में JSR107 एक तंत्र प्रदान करता हमेशा एनोटेट विधि आह्वान करने के लिए और अभी भी cacheResult # skipGet के माध्यम से परिणाम कैश। SkipGet पर एपीआई के अनुसार, यदि सही है तो एक फेंक दिया अपवाद के लिए पूर्व-आमंत्रण जांच भी छोड़ दी गई है। हालांकि, अगर आमंत्रण के दौरान एक अपवाद फेंक दिया जाता है तो इसे मानक अपवाद कैशिंग नियमों के बाद कैश किया जाएगा ताकि आपकी आवश्यकताओं के लिए पर्याप्त न हो। फिर भी, जेएसआर 107 का उपयोग करके आप कॉन्फ़िगरेशन पर कुछ अपवादों को स्पष्ट रूप से बहिष्कृत कर सकते हैं और शायद इससे आपको आगे बढ़ने की अनुमति मिल जाएगी। (NonCachedExceptions देखें) वसंत के अमूर्त JSR107 एनोटेशन सहायता प्रदान करता है। – TechTrip

2

अद्यतन इस जवाब अब पुरानी हो चुकी है, स्प्रिंग 3.2 और बाद के लिए टेक ट्रिप के answer देखें, ओपी: इसे स्वीकार्य के रूप में चिह्नित करने के लिए स्वतंत्र महसूस करें।

मुझे नहीं लगता कि यह संभव है (वहाँ भले ही वसंत में सशर्त कैश बेदखली कि गलत पर @CacheEvict पैरामीटर के साथ विधि मंगलाचरण के बाद क्रियान्वित किया जा सकता beforeInvocation सेट है, जो डिफ़ॉल्ट मान है) की जांच CacheAspectSupport वर्ग से पता चलता है लौटाया गया मूल्य inspectAfterCacheEvicts(ops.get(EVICT)); कॉल से पहले कहीं भी संग्रहीत नहीं किया जाता है।

protected Object execute(Invoker invoker, Object target, Method method, Object[] args) { 
    // check whether aspect is enabled 
    // to cope with cases where the AJ is pulled in automatically 
    if (!this.initialized) { 
     return invoker.invoke(); 
    } 

    // get backing class 
    Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target); 
    if (targetClass == null && target != null) { 
     targetClass = target.getClass(); 
    } 
    final Collection<CacheOperation> cacheOp = getCacheOperationSource().getCacheOperations(method, targetClass); 

    // analyze caching information 
    if (!CollectionUtils.isEmpty(cacheOp)) { 
     Map<String, Collection<CacheOperationContext>> ops = createOperationContext(cacheOp, method, args, target, targetClass); 

     // start with evictions 
     inspectBeforeCacheEvicts(ops.get(EVICT)); 

     // follow up with cacheable 
     CacheStatus status = inspectCacheables(ops.get(CACHEABLE)); 

     Object retVal = null; 
     Map<CacheOperationContext, Object> updates = inspectCacheUpdates(ops.get(UPDATE)); 

     if (status != null) { 
      if (status.updateRequired) { 
       updates.putAll(status.cUpdates); 
      } 
      // return cached object 
      else { 
       return status.retVal; 
      } 
     } 

     retVal = invoker.invoke(); 

     inspectAfterCacheEvicts(ops.get(EVICT)); 

     if (!updates.isEmpty()) { 
      update(updates, retVal); 
     } 

     return retVal; 
    } 

    return invoker.invoke(); 
} 
0

स्प्रिंग एनोटेशन

@Cacheable(value="defaultCache", key="#pk",unless="#result!=null") 

काम नहीं करता है, तो आप की कोशिश कर सकते हैं:

@CachePut(value="defaultCache", key="#pk",unless="#result==null") 

यह मेरे लिए काम करता है।

+5

क्या आपका मतलब था 'जब तक = "# परिणाम == शून्य" '? – cahen

+0

_Cache जब तक परिणाम! = Null_means _Cache यदि परिणाम == null_। तो, सही अभिव्यक्ति 'जब तक =" # परिणाम == अशक्त "' जो _Cache जब तक परिणाम का मतलब है == null_ जो _Cache अर्थ है कि यदि परिणाम! = Null_। – mmdemirbas