2015-05-10 7 views
6

मैं निम्नलिखित नियंत्रक कोड SpringMVC का उपयोग कर दिया है:SpringMVC नियंत्रक परत में, @Scope ("प्रोटोटाइप") बनाम @Scope ("सिंगलटन")

@Controller 
@Scope("prototype") 
@RequestMapping("/messages") 
public class MessageController { 
    @RequestMapping(value="/index", method=RequestMethod.GET) 
    @ResponseStatus(HttpStatus.OK) 
    @ResponseBody 
    public String displayAllMessages(ModelMap model) { 
     System.out.println(this.hashCode()); 
     // processing 
     return "messages"; 
    } 
} 

जब उपयोग @Scope("prototype"), प्रत्येक अनुरोध आता है, के उत्पादन में this.hashCode() अलग हैं, जिसका अर्थ है कि जब प्रत्येक अनुरोध आता है, तो एक नया MessageController उदाहरण बनाया जाएगा।

तो @Scope("prototype") का उपयोग नहीं, डिफ़ॉल्ट @Scope("singleton") हो जाएगा, प्रत्येक अनुरोध आता है, this.hashCode() के उत्पादन में ही कर रहे हैं, जिसका अर्थ है केवल एक MessageController उदाहरण बन जाता है।

मुझे यकीन नहीं है कि @Scope("prototype") का उपयोग कब करना चाहिए?

उत्तर

9

मान लें कि आपको एक सुअर की तरह कोड और है कि आपके नियंत्रक में की तरह कुछ करते हैं अनुरोध। नियंत्रक अब थ्रेड-सुरक्षित नहीं है। यदि इसे दो समवर्ती अनुरोधों को संभालने के लिए समवर्ती रूप से कहा जाता है, तो दौड़ की स्थिति हो सकती है।

नियंत्रक को प्रोटोटाइप बनाकर आप इस समस्या से बच सकते हैं: प्रत्येक अनुरोध को एक अलग नियंत्रक द्वारा संभाला जाएगा।

या आप सही काम कर सकते हैं और कोड स्टेटलेस बना सकते हैं, इस मामले में प्रत्येक अनुरोध के लिए एक नया नियंत्रक बनाना बेकार होगा, क्योंकि नियंत्रक स्टेटलेस होगा और इस प्रकार थ्रेड-सुरक्षित होगा। तब दायरा अपना डिफ़ॉल्ट मान रख सकता है: सिंगलटन।

public String displayAllMessages(ModelMap model) { 
    List<String> messages = fillMessages(); 
    model.put(messages, allMessages); 
    return "messages"; 
} 

private List<String> fillMessages() { 
    List<String> allMessages = new ArrayList<>(); 
    allMessages.add("hello world"); 
    return allMessages; 
} 
+0

मैं थोड़ी सी समस्या से फंस गया हूं। क्या आप कृपया मेरे प्रश्न में देख सकते हैं? http://stackoverflow.com/questions/43868299/how-to-reload-configuration-bean-with-properties-from-database – Lucky

1

यदि आप सिंगलटन का उपयोग करते हैं तो आपको यह सुनिश्चित करना होगा कि आप अपने नियंत्रक में स्थिति न रखें या आपके द्वारा किए गए किसी भी राज्य को आमंत्रण के बीच साझा करने के लिए डिज़ाइन किया गया हो। आम तौर पर व्यापार सेवा घटक इस तरह से बनाए जाते हैं और सिंगलटन नियंत्रक में इंजेक्ट करने के लिए सुरक्षित होते हैं।

ऐसे अन्य स्कोप भी हैं जिन्हें आप अपने वसंत विन्यास और पुस्तकालयों के आधार पर विचार कर सकते हैं।

आप बीन्स अनुरोध और सत्र स्कॉप्ड कर सकते हैं।

मैं प्रोटोटाइप स्कोप्ड के बजाय एक नियंत्रक वर्ग अनुरोध स्कॉप्ड करना चाहता हूं क्योंकि यह सुनिश्चित करेगा कि एक ही अनुरोध से नियंत्रक के एकाधिक उपयोग एक ही वस्तु प्राप्त कर रहे हैं।

यदि आप सत्र में एकाधिक अनुरोधों पर रखे गए राज्य को रखना चाहते हैं तो आप सत्र स्कोप का उपयोग कर सकते हैं। लेकिन वसंत @SessionAttributes

साथ एक ही बात को प्राप्त अंत में आप एक सिंगलटन सेम ProviderCreatingFactoryBean का उपयोग करते हुए एक java.inject.Provider के इंजेक्शन का उपयोग कर सकते करने के अन्य तरीकों है।

private List<String> allMessages; 

public String displayAllMessages(ModelMap model) { 
    allMessages = new ArrayList<>(); 
    fillMessages(); 
    model.put(messages, allMessages); 
    return "messages"; 
} 

private void fillMessages() { 
    allMessages.add("hello world"); 
} 

आपका नियंत्रक स्टेटफुल बन जाएगा: यह एक राज्य (allMessages) है कि दोनों के बीच साझा नहीं किया जा सकता है

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