2015-04-22 8 views
5

मुझे पता है कि इसके बारे में बहुत सारे प्रश्न हैं। मैंने उनमें से बहुत से देखा लेकिन समस्या अभी भी बनी हुई है।स्प्रिंग बीन्स बनाया गया लेकिन स्वायत्त नहीं

मेरे पास एक सेवा है जो बनाई गई है लेकिन स्वतः नहीं है। कोई (!) मैन्युअल दीक्षा नहीं है, न तो परियोजना में और न ही परीक्षणों में (जैसे this question)

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

सेवा (इंटरफेस):

public interface SchoolService { 
    public School getSchool(String id); 
} 

सेवा (कार्यान्वयन):

@Service 
@Transactional 
public class SchoolServiceImpl implements SchoolService { 

    @Autowired 
    private SchoolDAO schoolDAO; 

    public School getSchool(String id) { 
    //database things 
    return school; 
    } 

} 

हो जाता है जहां यह "कहा जाता है"

public class SchoolMenu implements Serializable { 

    @Autowired 
    private SchoolService schoolService; 

    public SchoolMenu() { 
    //here schoolService is null 
    School school = schoolService.getSchool("id"); 
    } 

} 

आवेदन-context.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" 
     xmlns:p="http://www.springframework.org/schema/p" 
     xmlns:aop="http://www.springframework.org/schema/aop" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 


    <bean id="SchoolServiceImpl" class="content_management.School.service.SchoolServiceImpl"/> 
    <bean id="SchoolDAOImpl" class="content_management.School.dao.SchoolDAOImpl"/> 
</beans> 

बिलाव आउटपुट:

org.springframework.beans.factory.support.DefaultListableBeanFactory: Pre-instantiating singletons in org.s[email protected]57003970: defining beans [SchoolServiceImpl,SchoolDAOImpl]; root of factory hierarchy 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating shared instance of singleton bean 'SchoolServiceImpl' 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating instance of bean 'SchoolServiceImpl' 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Eagerly caching bean 'SchoolServiceImpl' to allow for resolving potential circular references 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Finished creating instance of bean 'SchoolServiceImpl' 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating shared instance of singleton bean 'SchoolDAOImpl' 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating instance of bean 'SchoolDAOImpl' 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Eagerly caching bean 'SchoolDAOImpl' to allow for resolving potential circular references 
org.springframework.beans.factory.support.DefaultListableBeanFactory: Finished creating instance of bean 'SchoolDAOImpl' 

मेरे त्रुटि है?

+0

आप निर्माता से क्षेत्र का उपयोग करने से पहले स्प्रिंग कुछ भी करने को का अवसर मिल सके प्रयास कर रहे हैं। – chrylis

उत्तर

2

@Autowired के लिए काम करने के लिए, SchoolMenu भी वसंत बीन होना चाहिए। यदि ऐसा नहीं है, तो आप आवेदन संदर्भ से schoolService प्राप्त कर सकते हैं। इस

ApplicationContext appContext = new ClassPathXmlApplicationContext("application-context.xml"); 
SchoolService schoolService = (SchoolService) appContext.getBean(SchoolService.class); 
1

आप SchoolMenu के निर्माता में schoolService पहुँच बना रहे हैं की तरह कुछ:

public SchoolMenu() { 
    //here schoolService is null 
    School school = schoolService.getSchool("id"); 
} 

उस समय, schoolService अभी तक इंजेक्शन नहीं है। यह नहीं हो सकता - से पहले कुछ भी नहीं हो सकता है कन्स्ट्रक्टर का आह्वान किया गया है।

javax.annotation.PostConstruct एनोटेशन के साथ एनोटेट करके, बीन शुरू होने के बाद आप एक विधि घोषित करने के लिए घोषणा कर सकते हैं। उन क्रियाओं को करें जिन्हें उस विधि में इंजेक्शन निर्भरताओं की आवश्यकता है, कन्स्ट्रक्टर में नहीं।

(जैसे InitializingBean इंटरफेस को लागू करने के रूप में प्राप्त करने के लिए कुछ अन्य तरीके एक ही है, कर रहे हैं, लेकिन इन कर रहे हैं एक सा पुराना)

उदाहरण:

public SchoolMenu() { 
} 

@PostConstruct 
public void init() { 
    // schoolService is NOT null here 
    School school = schoolService.getSchool("id"); 
} 
+1

पहले स्थान पर कन्स्ट्रक्टर इंजेक्शन का उपयोग करना और भी बेहतर है। – chrylis

+0

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

+1

हां, लेकिन (1) यहां तक ​​कि यह मामला नहीं है जहां तक ​​मैं कह सकता हूं और (2) चक्रीय निर्भरता लगभग हमेशा एक डिजाइन समस्या का संकेत है। – chrylis

0
इसके बजाय एक्सएमएल में सेम को परिभाषित करने के

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

<context:component-scan base-package="content_management.School" /> 

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

<?xml version='1.0' encoding='UTF-8' ?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

<context:component-scan base-package="content_management.School" /> 

</beans> 
+0

मैंने दोनों नामस्थान और स्कैन स्निपेट को जोड़ा, लेकिन मुझे 'XmlBeanDefinitionStoreException: ServletContext संसाधन [/WEB-INF/applicationContext.xml] से XML दस्तावेज़ में पंक्ति 26 अमान्य है; नेस्टेड अपवाद org.xml.sax.SAXParseException है; लाइन संख्या: 26; कॉलम संख्या: 78; cvc-complex-type.2.4.c: ' – sebastian

+0

क्या आप अपने अनुप्रयोग Context.xml की लाइन 26 या पूरी फ़ाइल को बेहतर भी दिखा सकते हैं? ऐसा लगता है कि सिंटैक्स त्रुटि –

+0

लाइन 26 '<संदर्भ: ...' पंक्ति है, मैंने बस – sebastian

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