2013-02-27 120 views
12

को लागू करते समय ApplicationContext.getBean() का उपयोग करने से कैसे बचें I बस स्प्रिंग आईओसी अवधारणा के साथ शुरू कर रहा हूं। मैं अक्सर इंटरनेट में पाए गए अधिकांश उदाहरण ऑब्जेक्ट प्राप्त करने के लिए कोड का उपयोग करता हूं।स्प्रिंग आईओसी

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml"); 
Hello hello = (Hello) appContext.getBean("hello"); 

इन सवालों से एक संदर्भ के रूप में 1 और stackoverflow में 2। मैंने अनुमान लगाया है कि कोड में appContext.getBean ("हैलो") का उपयोग करना आवश्यक नहीं है जिसे खराब अभ्यास माना जाता है। इसके अलावा, अब और अनुशंसित नहीं है। मुझे यहां सही करें, अगर मेरा अनुमान गलत है।

ध्यान में रखते हुए, मैंने तदनुसार अपनी परियोजना में बदलाव किए हैं। यहाँ मेरी applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> 
<bean id="utilClassRef" class="org.hd.derbyops.DUtils" lazy-init="false" /> 
<bean id="appContext" class="org.hd.derbyops.ContextProvider" lazy-init="false"> 
    <property name="utils" ref="utilClassRef" /> 
</bean> 
</beans> 

मेरे contextProvider कक्षा कोड

public class ContextProvider implements ApplicationContextAware { 

    private static ApplicationContext ctx; 

    /** 
    * Objects as properties 
    */ 
    private static DUtils utils; 

    public void setApplicationContext(ApplicationContext appContext) 
      throws BeansException { 
     ctx = appContext; 

    } 

    public static ApplicationContext getApplicationContext() { 
     return ctx; 
    } 

    public static DUtils getUtils() { 
     return utils; 
    } 

    public void setUtils(DUtils dUtilsRef) { 
     utils = dUtilsRef; 
    } 

} 

उदाहरण के लिए, एक वर्ग एक कि org.hd.derbyops.DUtils पर निर्भर करता है पर विचार है। मैं पाने के लिए निम्न कोड लाइन

ContextProvider.getUtils(); 

inorder उपयोग कर रहा हूँ DUtils वर्ग ए में वस्तु, इस प्रकार मेरी कोड में कहीं भी ApplicationContext.getBean() के उपयोग से परहेज।

मान लें, अगर मेरे पास 10 कक्षाएं हैं और मेरी कक्षा ए उन सभी पर निर्भर है, जिनकी वस्तुओं को ApplicationContext.getBean() का उपयोग किये बिना बनाया और एक्सेस किया जाना है। उस मामले में, जैसा कि ऊपर किया गया है, मेरे पास ContextProvider क्लास के गुण बनाने के बाद सोटर और उस संपत्ति के गेटर का विचार है, जहां get<PropertyName> स्थिर है। इसलिए, मैं इसे किसी ऑब्जेक्ट की आवश्यकता होने पर भी उपयोग कर सकता हूं, जैसे

ContextProvider.get<PropertyName>; 

मेरा संक्षिप्त प्रश्न यहां दिया गया है। सबसे पहले, क्या मेरा दृष्टिकोण सही है? यदि यह सही है, स्टार्ट-अप पर सभी सेम लोड करना, क्या यह प्रदर्शन हत्यारा नहीं होगा? आप अपने आवेदनों में कम से कम एक बार से अधिक बार कॉल करने के बिना कैसे करेंगे?

यदि आप एक वेब-एप्लिकेशन & डिज़ाइन करना चाहते थे तो आप किसी भी कोड में ApplicationContext.getBean() का उपयोग किये बिना स्प्रिंग आईओसी को लागू करना चाहते थे। आप वह कैसे करेंगें?

नोट: अन्य प्रश्न के संदर्भ में

ApplicationContext.getBean कॉलिंग ऊपर टैग किए गए() नियंत्रण के उलट नहीं है!

+0

आप वसंत MVC उपयोग कर रहे हैं या बुनियादी servlets का उपयोग करने की कोशिश कर रहा है? –

+0

मैं स्प्रिंग एमवीसी का उपयोग नहीं कर रहा हूं, बस आईओसी – srk

+2

के लिए इसका उपयोग कर रहा हूं, सामान्य रूप से, * किसी को * 'एप्लिकेशनकॉन्टेक्स्ट' से बीन प्राप्त करने की आवश्यकता होगी। आदर्श रूप में, इसे केवल एक बार बुलाया जा रहा है, और यह बूटस्ट्रैपिंग ऑब्जेक्ट द्वारा होगा ... –

उत्तर

9

सरल उत्तर हाँ और नहीं, नहीं, और नहीं हैं। और अंत में, वसंत एमवीसी के लिए ऑनलाइन खोज करें, क्योंकि यह शायद आप जो चाहते हैं वह करता है।

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

  • आप उन्हें यूनिट परीक्षण के लिए नकल नहीं कर सकते (आप जुनीट का उपयोग कर रहे हैं?)
  • आप विरासत के साथ उनका उपयोग नहीं करते
  • स्टेटिक initialisers एक शानदार तरीका है अपवाद
  • आदि, आदि

तो, हाँ इंजेक्शन के लिए, और स्थिर सामान के लिए कोई ढीला करने के लिए।

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

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

अंत में, यदि आप स्टार्टअप पर कक्षा में सभी निर्भरताओं को इंजेक्ट करते हैं, और आप इसे अपने सभी वर्गों के साथ करते हैं, तो आपको किसी भी तरह की चीज़ों को पूरा करने की आवश्यकता नहीं है। इसके अलावा, init-method और destroy-method बीन पर विशेषताओं का उपयोग करने का अर्थ है कि वसंत समाप्त हो जाने के बाद आप प्रक्रियाओं को शुरू कर सकते हैं। आपको केवल संदर्भ लोड करने की आवश्यकता है, और आपका ऐप अस्तित्व में वसंत (पन इरादा) होगा।

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

+0

mycompany में, मैंने कभी भी 'ApplicationContext.getBean() 'और सामान नहीं देखा है। लेकिन ऐसा इसलिए है क्योंकि ये उद्यम स्तर के वेब अनुप्रयोग हैं। तो मेरे लिए मेरे सभी वर्गों को वास्तव में क्या लोड करता है? क्या यह सर्वर है जो करता है? – Kraken

+0

आम तौर पर आप पूर्व-डिब्बाबंद स्प्रिंग एप्लिकेशन लोडिंग कक्षाओं में से एक का उपयोग करते हैं, जो मानक जेईई घटक हैं जैसे सर्वलेट्स और व्हाट्नॉट। फिर ये सभी वसंत आईओसी सामानों को लात मार देते हैं। उन वर्गों के आंतों में दूर टकराए गए, एक्सएमएल फ़ाइल से एप्लिकेशन संदर्भ बनाने के लिए एक कॉल होगा, इसे वर्तमान में चल रहे एप्लिकेशन के साथ संबद्ध करें, और एप्लिकेशन संदर्भ को किसी भी तरीके से उपलब्ध कराएं। – Jimadilo

1

पर वास्तव में getBean() पर कॉल किए बिना पहला उदाहरण प्राप्त करने के लिए मेरा उदाहरण यहां दिया गया है।

public class Test{ 
    // Declare private static variable so that we can access it in main() 
    private static Triangle triangle; 

    // Use constructor injection to set the triangle 
    public Test(Triangle triangle) { 
     Test.triangle = triangle; 
    } 

    public static void main(String[] args) { 
     // Specify the context file containing the bean definitions 
     // Spring automatically creates instances of all the beans defined 
     // in this XML file. This process is performed before you actually make 
     // a getBean("beanName") call. 
     ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 

     // Use instance methods of triangle 
     Test.triangle.draw(); 
    } 
} 

आप किसी अन्य तरीके से उपयोग कर सकते हैं: अपने मुख्य वर्ग के लिए अब

spring.xml में (आपका सेम विन्यास एक्सएमएल फ़ाइल)

<bean class="com.example.Test" init-method="myMethod"> 
    <constructor-args ref="triangle"/> 
</bean> 

public class Test { 
    private final Triangle triangle; 

    public Test (Triangle triangle) { 
    this.triangle = triangle; 
    } 

    public static void main (String[] args) { 
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 
    } 

    // Called by Spring immediately after the Triangle Bean has been created and 
    // all the properties for the bean have been set. This method name must match 
    // the one specified with destroy-method attribute in spring.xml 
    public void myMethod() { 
    triangle.draw(); 
    } 
}