2012-04-14 9 views
5

क्या गैर-सिंगलटन (उदा। सत्र-स्कोप्ड) बीन के साथ स्प्रिंग के @Cacheable एनोटेशन का उपयोग करने का कोई आसान तरीका है और क्या कैश के समान बीप कहा गया है?क्या वसंत की @ कैशेबल एनोटेशन में एनोटेटेड विधि के बीन के समान स्कोप हो सकता है?

उदाहरण:

import javax.inject.Inject; 
import javax.inject.Named; 

import org.springframework.cache.annotation.Cacheable; 
import org.springframework.context.annotation.Scope; 
import org.springframework.security.core.context.SecurityContextHolder; 

@Named 
@Scope("session") 
public class UserNameRetriever { 

    @Inject private UserDao userDao; 

    @Cacheable("userName") 
    public String getUserName() { 
     return userDao.getUserByLogin((String)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName(); 
    } 

} 

आदर्श रूप में, UserNameRetriever.getUserName()UserDao प्रति सत्र एक बार से उपयोगकर्ता नाम लाने होगा, लेकिन इस कोड को वास्तव में आवेदन चौड़ा संचित करता है।

उत्तर

2

मैं इसे करने की कोशिश नहीं की है, लेकिन Spring reference के अनुसार मुझे लगता है कि यह काम करेगा:

@Cacheable(value = "userName", key = "#root.target") 
+0

यह काम करता है, लेकिन बिना ( \t \ @CacheEvict (मूल्य = "उपयोगकर्ता नाम" एक स्मृति रिसाव, कुंजी = "# root.target" है) \t \ @PreDestroy \t सार्वजनिक शून्य सफाई() { \t} ) इसके अलावा, मैंने निर्णय लिया है कि @Cacheable का उपयोग न करें, क्योंकि यह गारंटी नहीं देता है कि मान केवल एक बार गणना की जाएगी। –

+0

स्मृति रिसाव से आपका क्या मतलब है? शायद आपका कैश बहुत बड़ा है। @ कैशेबल पहले कैश में लुकअप करेगा, इसलिए यह गारंटी देता है कि कैश में अभी भी मान की गणना नहीं की जाएगी। – sinuhepop

+0

यह एक स्मृति रिसाव है क्योंकि सत्र समाप्त होने के बाद, मान अभी भी कैश में है, लेकिन इसका उपयोग नहीं किया जा सकता है। @PreDestroy यह सुनिश्चित करता है कि सत्र समाप्त होने पर कैश किए गए मान को निकाल दिया जाए। –

2

मुझे लगता है कि आप गलत पक्ष से समस्या का सामना कर रहे हैं। "स्थानीय" होने के बजाय सत्र-स्कॉप्ड कैश केवल एक मान को संग्रहीत करते हैं, एक वैश्विक कैश उपयोगकर्ता नाम से मानचित्र को User मानों में संग्रहीत करता है।

आपके मामले में getUserName() पर छोड़ @Cacheable और UserDao पर डाल दिया:

public class UserDao { 
    @Cacheable("users") 
    public User getUserByLogin(String user) { 
    //... 
    } 
} 

इतना ही नहीं कैश की अधिक मुहावरेदार उपयोग है, लेकिन यह भी इसे बनाए रखने और बेहतर प्रदर्शन करने के लिए आसान साबित होगा।

अपने मूल प्रश्न पर वापस जाएं: नहीं, यह बॉक्स के बाहर संभव नहीं है। आपको मौजूदा कार्यान्वयन के आसपास अपना CacheManager - शायद लिखना होगा।

+0

आरई: मुझे लगता है कि आप गलत पक्ष से समस्या का सामना कर रहे हैं: उपयोगकर्ताडाओ उपयोगकर्ता को बाहरी सिस्टम से लाता है, और मैं एक सत्र में लगातार उपयोगकर्ता नाम (केवल कॉस्मेटिक रूप से उपयोग किया जाता हूं) चाहता हूं, लेकिन नए सत्र में रीफ्रेश करें यह बाहरी प्रणाली में बदल गया है। आपका दृष्टिकोण इस व्यवहार को प्रदर्शित नहीं करेगा। –

3

आप एक सत्र कैश चाहते हैं, सत्र का उपयोग करें। यही है, उपयोगकर्ता को सत्र-स्कोप्ड बीन में एक निजी क्षेत्र में स्टोर करें, या सीधे HttpSession ऑब्जेक्ट तक पहुंचें। @Cacheable आमतौर पर एप्लिकेशन-व्यापी संसाधनों के लिए है।

ठीक है, आप key="#user.id" उपयोग कर सकते हैं, और कैश (स्वयं या @CacheEvict साथ) एक @PreDestroy पद्धति पर रद्द करने के लिए, लेकिन यह बेहतर होगा अगर आप दो मिश्रित नहीं होते हैं - कैशिंग और सत्र डेटा।

+0

हाय @ बोझो क्या आप कृपया यह साबित कर सकते हैं कि आपको लगता है कि वसंत वेब एप्लिकेशन में httpsession vs कैशेबल का उपयोग करना बेहतर क्यों है? –

+0

यह सत्र-व्यापी बनाम एप्लिकेशन-व्यापी संसाधन है। यदि आप सत्र संसाधनों के लिए @Cacheable का उपयोग करना चाहते हैं तो यह अतिरिक्त प्रयास है – Bozho

संबंधित मुद्दे