2010-04-14 22 views
74

जैसा कि हम सभी जानते हैं कि हमारे पास स्प्रिंग कंटेनर में डिफ़ॉल्ट रूप से सिंगलटन के रूप में बीन्स हैं और यदि हमारे पास स्प्रिंग फ्रेमवर्क के आधार पर एक वेब एप्लिकेशन है तो उस मामले में हमें वास्तव में सिंगलटन डिज़ाइन पैटर्न को लागू करने की आवश्यकता है बस वसंत के माध्यम से एक बीन बनाने के बजाय वैश्विक डेटा पकड़ने के लिए।स्प्रिंग कंटेनर में सिंगलटन बीन्स बनाम सिंगलटन डिज़ाइन पैटर्न

अगर मैं समझाने में सक्षम नहीं हूं कि मैं वास्तव में क्या पूछना चाहता हूं तो कृपया मेरे साथ भालू।

उत्तर

9

वसंत में सिंगलटन गुंजाइश का अर्थ है कि इस बीन को वसंत द्वारा केवल एक बार तत्काल किया जाएगा। प्रोटोटाइप स्कोप (प्रत्येक बार नया उदाहरण) के विपरीत, अनुरोध स्कोप (अनुरोध के बाद एक बार), सत्र स्कोप (एक बार प्रति HTTP सत्र)।

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

+0

अगर मैं गलत हूं तो मुझे सही करें यदि मुझे किसी ऑब्जेक्ट को सिंगलटन के रूप में लागू करने की आवश्यकता है तो सिंगलटन पैटर्न को लागू करने की आवश्यकता नहीं है। वसंत का उपयोग कर बीन बनाना काम करेगा।स्प्रिंग ढांचे में सिंगलटन डिजाइन पैटर्न और सिंगलटन स्कोप से संबंधित मेरी समझ के साथ अब मैं थोड़ी उलझन में हूं। – Peeyush

+1

वसंत आपको सिंगलटन पैटर्न का उपयोग करने के लिए मजबूर नहीं करता है। – lexicore

46

वसंत में सिंगलटन बीन और सिंगलटन पैटर्न काफी अलग हैं। सिंगलटन पैटर्न का कहना है कि एक विशेष वर्ग का एक और एक उदाहरण प्रति क्लासलोडर कभी बनाया जाएगा।

स्प्रिंग सिंगलटन का दायरा "प्रति कंटेनर प्रति बीन" के रूप में वर्णित है। यह स्प्रिंग आईओसी कंटेनर प्रति एक ऑब्जेक्ट उदाहरण के लिए बीन परिभाषा का दायरा है। वसंत में डिफ़ॉल्ट दायरा सिंगलटन है।

हालांकि डिफ़ॉल्ट दायरा सिंगलटन है, फिर भी आप <bean ../> तत्व के दायरे विशेषता को निर्दिष्ट करके बीन के दायरे को बदल सकते हैं।

<bean id=".." class=".." scope="prototype" /> 
+7

@ user184794: प्रति कंटेनर प्रति कंटेनर, जिसका मतलब वसंत कंटेनर में केवल एक क्लासलोडर है। अगर वसंत कंटेनर में दो या दो से अधिक क्लासलोडर हैं, तो प्रत्येक क्लासलोडर का अपना उदाहरण होगा। क्या इसका मतलब है "प्रति कंटेनर प्रति प्रति लोडर प्रति बीन"। कृपया स्पष्ट करें !! –

+4

मुझे लगता है कि इसका मतलब है कि एक वसंत कंटेनर एक एकल क्लासलोडर का उपयोग करेगा जिसका मालिक है। वसंत के तंत्र के बाहर आप जो करते हैं वह प्रासंगिक नहीं है, यानी आप अपने स्वयं के क्लासलोडर बना सकते हैं और अपनी इच्छा के अनुसार कक्षा के कई उदाहरण बना सकते हैं, लेकिन यदि आप स्प्रिंग कंटेनर से गुज़रते हैं, तो यह एक से अधिक उदाहरण नहीं बनायेगा – inor

+0

फिर जैसा कि आप कहते हैं, वे "काफी अलग" नहीं हैं। केवल अंतर ही गुंजाइश है - स्प्रिंग कंटेनर छंद श्रेणी लोडर –

1

वसंत में "सिंगलटन" बीन कारखाने का उपयोग उदाहरण का उपयोग कर रहा है, फिर इसे कैश करें; जो सिंगलटन डिज़ाइन पैटर्न कड़ाई से है, उदाहरण केवल स्थिर प्राप्त विधि से पुनर्प्राप्त किया जा सकता है, और ऑब्जेक्ट को सार्वजनिक रूप से तुरंत चालू नहीं किया जा सकता है।

25

वसंत में सिंगलटन गुंजाइश का अर्थ स्प्रिंग संदर्भ में एक उदाहरण है ..
वसंत कंटेनर बीन प्राप्त करने के लिए बाद में कॉल के लिए बार-बार एक ही उदाहरण देता है। यदि सेम के वर्ग सिंगलटन के रूप में है या नहीं कोडित है


और वसंत परेशान नहीं करता है, वास्तव में अगर वर्ग सिंगलटन निजी के रूप में जिसका निर्माता रूप में कोडित है, स्प्रिंग BeanUtils.instantiateClass (जावाडोक here) का उपयोग निर्माता स्थापित करने के लिए सुलभ और इसे आमंत्रित करने के लिए।

वैकल्पिक रूप से, हम इस

<bean id="exampleBean" class="example.Singleton" factory-method="getInstance"/> 
+1

क्या आप वाकई फैक्ट्री-विधि विशेषता की आवश्यकता है? मुझे पूरा यकीन है कि स्प्रिंग जानता है कि कन्स्ट्रक्टर निजी है (संभवतया प्राप्त करने का प्रयास करने का प्रयास करता है) – inor

+0

स्प्रिंग कैसे निजी कन्स्ट्रक्टर का आह्वान करता है [http://stackoverflow.com/a/7254617/) पर एक संबंधित चर्चा 2841265) –

2

वसंत में सिंगलटन सेम और कक्षाओं सिंगलटन डिजाइन पैटर्न के आधार पर की तरह सेम परिभाषा में एक कारखाने में विधि विशेषता का उपयोग कर सकते हैं काफी अलग हैं।

सिंगलटन पैटर्न यह सुनिश्चित करता है कि एक विशेष वर्ग का एक और एक उदाहरण प्रति क्लासलोडर कभी बनाया जाएगा, जहां एक स्प्रिंग सिंगलटन बीन के दायरे को 'प्रति कंटेनर प्रति बीन' के रूप में वर्णित किया गया है। वसंत में सिंगलटन गुंजाइश का मतलब है कि इस बीन को वसंत द्वारा केवल एक बार तत्काल किया जाएगा। वसंत कंटेनर बीन प्राप्त करने के लिए बाद में कॉल के लिए बार-बार एक ही उदाहरण देता है।

+10

आप 'जावा मावेरिक' हैं, है ना? इससे आपका बयान होगा, "एक अच्छी व्याख्या और उदाहरण मिला ..." यह छिपाने का एक बेईमान प्रयास है कि आप अपनी वेबसाइट से जुड़ रहे हैं। आपका लिंक जवाब के लिए महत्वपूर्ण नहीं प्रतीत होता है, वैसे भी। स्पैम के रूप में हटाए जाने वाले उत्तर से बचने के लिए, मैं इसे हटा रहा हूं। अपनी वेबसाइट पर और अधिक लिंक पोस्ट करने से पहले कृपया स्व-संवर्धन पर अक्सर पूछे जाने वाले प्रश्न पढ़ें। यह भी ध्यान रखें कि आपके वेबसाइट लिंक को अपनी प्रोफ़ाइल में रखना बहुत अच्छा है। –

15

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

यदि आप स्प्रिंग फ्रेमवर्क का उपयोग नहीं कर रहे हैं, तो सिंगलटन पैटर्न यह सुनिश्चित करता है कि आपके आवेदन में कक्षा के एक से अधिक उदाहरण नहीं होंगे। ऐसा इसलिए है क्योंकि आप 'नया' करके कक्षा के उदाहरणों को तत्काल नहीं कर सकते क्योंकि निर्माता निजी है। कक्षा का उदाहरण प्राप्त करने का एकमात्र तरीका वर्ग की कुछ स्थैतिक विधि को कॉल करना है (आमतौर पर 'getInstance' कहा जाता है) जो हमेशा एक ही उदाहरण देता है।

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

आम तौर पर यदि आप वसंत का उपयोग कर रहे हैं, तो आपको केवल उदाहरण बनाने के लिए वसंत का उपयोग करना चाहिए, और आप कक्षा के लिए एक सार्वजनिक निर्माता हो सकते हैं। लेकिन अगर आपका कन्स्ट्रक्टर निजी नहीं है तो आप स्प्रिंग को छोड़कर सीधे कक्षा के नए उदाहरण बनाने से किसी को भी रोक नहीं रहे हैं।

यदि आप वास्तव में कक्षा के एक उदाहरण चाहते हैं, भले ही आप अपने आवेदन में स्प्रिंग का उपयोग करें और स्प्रिंग में वर्ग को सिंगलटन के रूप में परिभाषित करें, यह सुनिश्चित करने का एकमात्र तरीका है कि सिंगलटन पैटर्न का उपयोग करके कक्षा को भी लागू किया जाए। यह सुनिश्चित करता है कि एक उदाहरण होगा, चाहे लोग स्प्रिंग का उपयोग उदाहरण प्राप्त करने या वसंत को बाईपास करने के लिए करते हैं।

1

EX: "प्रति कंटेनर प्रति बीन"।

 <bean id="myBean" class="com.spring4hibernate4.TestBean"> 
      <constructor-arg name="i" value="1"></constructor-arg> 
      <property name="name" value="1-name"></property> 
     </bean> 

     <bean id="testBean" class="com.spring4hibernate4.TestBean"> 
      <constructor-arg name="i" value="10"></constructor-arg> 
      <property name="name" value="10-name"></property> 
     </bean> 
    </beans> 



    public class Test { 

     @SuppressWarnings("resource") 
     public static void main(String[] args) { 
      ApplicationContext ac = new ClassPathXmlApplicationContext("ws.xml"); 
      TestBean teatBean = (TestBean) ac.getBean("testBean"); 
      TestBean myBean1 = (TestBean) ac.getBean("myBean"); 
      System.out.println("a : " + teatBean.test + " : " + teatBean.getName()); 
      teatBean.setName("a TEST BEAN 1"); 
      System.out.println("uPdate : " + teatBean.test + " : " + teatBean.getName()); 
      System.out.println("a1 : " + myBean1.test + " : " + myBean1.getName()); 
      myBean1.setName(" a1 TEST BEAN 10"); 
      System.out.println("a1 update : " + teatBean.test + " : " + myBean1.getName()); 
     } 
    } 

public class TestBean { 
    public int test = 0; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    private String name = "default"; 

    public TestBean(int i) { 
     test += i; 
    } 
} 

जावा SINGLETON:

public class Singleton { 
    private static Singleton singleton = new Singleton(); 
    private int i = 0; 

    private Singleton() { 
    } 

    public static Singleton returnSingleton() { 

     return singleton; 
    } 

    public void increment() { 
     i++; 
    } 

    public int getInt() { 
     return i; 
    } 
} 

public static void main(String[] args) { 
     System.out.println("Test"); 

     Singleton sin1 = Singleton.returnSingleton(); 
     sin1.increment(); 
     System.out.println(sin1.getInt()); 
     Singleton sin2 = Singleton.returnSingleton(); 
     System.out.println("Test"); 
     sin1.increment(); 
     System.out.println(sin1.getInt()); 
    } 
+0

<सेम वर्ग = "com.spring4hibernate4.TestBean"> \t \t <निर्माता-आर्ग नाम = "मैं" value = "1"> \t \t <संपत्ति नाम = "नाम" value = " 1-नाम "> \t \t <सेम वर्ग =" com.spring4hibernate4.TestBean "> \t \t <निर्माता-आर्ग नाम =" मैं "मान =" 10 "> \t \t <संपत्ति का नाम = "नाम" मूल्य = "10-नाम"> \t – Hariprasad

0

स्प्रिंग सिंगलटन सेम के रूप में 'प्रति कंटेनर प्रति सेम' में वर्णित है। वसंत में सिंगलटन गुंजाइश का अर्थ है कि उसी स्मृति स्थान पर एक ही वस्तु उसी बीन आईडी पर वापस कर दी जाएगी। यदि कोई एक ही कक्षा के विभिन्न आईडी के कई सेम बनाता है तो कंटेनर विभिन्न ऑब्जेक्ट्स को विभिन्न आईडी में वापस कर देगा। यह एक महत्वपूर्ण मूल्य मैपिंग की तरह है जहां कुंजी बीन आईडी है और मान एक वसंत कंटेनर में बीन ऑब्जेक्ट है। जहां सिंगलटन पैटर्न सुनिश्चित करता है कि प्रति वर्ग लोडर के लिए एक विशेष वर्ग का एक और केवल एक उदाहरण बनाया जाएगा।

1

मुझे "प्रति कंटेनर प्रति बीन" मिलना मुश्किल लगता है। मैं कहूंगा "एक बीन प्रति बीन आईडी"। इसका समझने के लिए एक उदाहरण है। हमारे पास एक बीन वर्ग नमूना है। मैं की तरह सेम परिभाषा इस वर्ग से दो सेम परिभाषित किया है,:

<bean id="id1" class="com.example.Sample" scope="singleton"> 
     <property name="name" value="James Bond 001"/>  
</bean>  
<bean id="id7" class="com.example.Sample" scope="singleton"> 
     <property name="name" value="James Bond 007"/>  
</bean> 

तो जब कभी मैं आईडी "ID1" के साथ सेम प्राप्त करने की कोशिश, वसंत कंटेनर एक सेम यह पैदा करेगा, कैश और एक ही सेम वापसी जहां कभी id1 के साथ प्रस्तुत किया गया। यदि मैं इसे id7 के साथ प्राप्त करने का प्रयास करता हूं, तो एक और बीन नमूना वर्ग से बनाया जाएगा, उसी बार कैश किया जाएगा और प्रत्येक बार जब आपने आईडी 7 के साथ संदर्भित किया होगा।

यह सिंगलटन पैटर्न के साथ असंभव है। सिंगलटन पैटर्न में एक वर्ग प्रति वर्ग लोडर हमेशा बनाया जाता है। लेकिन वसंत ऋतु में एक ही कक्षा के लिए कई वस्तुओं का निर्माण किया जा रहा है। हालांकि स्प्रिंग में सिंगलटन एक ही आईडी के लिए एक ही ऑब्जेक्ट लौटने के दायरे को बना रहा है। Reference

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