2011-12-01 11 views
7

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

@Service 
    object UserRest extends RestHelper { 
     @Autowired 
     @BeanProperty 
     val userRepository: UserRepository = null; 

     ..... 
    } 

    <beans> 
     ..... 
     <bean id="userRest" class="com.abc.rest.UserRest" > 
       <!--- this is my attempt to manually wire it ---> 
       <property name="userRepository" ref="userRepository"/> 
     </bean> 
    </beans> 
+0

आपको यहां किसी ऑब्जेक्ट की आवश्यकता क्यों है? वैसे भी '@ सेवा वर्ग हैलो {@Autowired var repo: रिपोजिटरी = _}' को ठीक काम करना चाहिए, मान लें कि आपने घटक-स्कैन कॉन्फ़िगर किया है या एनोटेशन कॉन्फिग एप्प्लिकेशन कॉन्टेक्स्ट – OlegYch

उत्तर

12

मूल रूप से, आप दो समस्याएं हैं: जबकि वसंत उदाहरण के तरीकों की उम्मीद

  • संपत्ति परिवर्तनशील होना चाहिए, जैसे कि var बजाय val

  • स्काला object के सभी तरीकों, static हैं। असल में स्कैला दृश्य के पीछे UserRest$ नामक विधियों के साथ एक वर्ग बनाता है, और आपको स्प्रिंग के लिए इसके सिंगलटन इंस्टेंस UserRest$.MODULE$ को बनाने की आवश्यकता है।
    वसंत पूर्ववर्ती सिंगलटन उदाहरणों के लिए कॉन्फ़िगरेशन लागू कर सकता है, लेकिन उन्हें एक विधि द्वारा वापस किया जाना चाहिए, जबकि UserRest$.MODULE$ एक फ़ील्ड है। इस प्रकार, आपको इसे वापस करने के लिए एक विधि बनाने की आवश्यकता है।

तो, कुछ इस तरह काम करना चाहिए:

object UserRest extends RestHelper { 
    @BeanProperty 
    var userRepository: UserRepository = null; 

    def getInstance() = this 
    ... 
} 

<bean id="userRest" 
    class="com.abc.rest.UserRest" 
    factory-method = "getInstance"> 
    <property name="userRepository" ref="userRepository"/> 
</bean> 

आप @Autowired साथ <property> की जगह ले सकता है, लेकिन ऊपर वर्णित सिंगलटन उदाहरण की समस्याओं के कारण @Service साथ मैनुअल सेम घोषणा बदल नहीं सकते।

यह भी देखें:

+0

का उपयोग करना बहुत अच्छा है। मुझे आश्चर्य है कि स्प्रिंग 3.1 के साथ ऐसा करने का एक गैर-एक्सएमएल तरीका है या नहीं। – sourcedelica

+0

@ericacm: असल में, आप एक '@ कॉन्फ़िगरेशन' ऑब्जेक्ट बना सकते हैं और 'UserRest $' वापस लौटा सकते हैं। 'बीन' एनोटेटेड विधि से $ $। यह स्प्रिंग 3.0 में पहले से ही उपलब्ध है। – axtavt

+0

हां - अच्छा बिंदु। – sourcedelica

1

मुझे क्या AutowiredAnnotationBeanPostProcessor का उपयोग निर्माण समय में वस्तु इंजेक्षन करने के लिए है।

उदाहरण के लिए:

object UserRest extends RestHelper { 
    @Autowired 
    var userRepository: UserRepository = _ 

    AppConfig.inject(this) 
} 

@Configuration 
class AppConfig extends ApplicationListener[ContextRefreshedEvent] { 

    // Set the autowiredAnnotationBeanPostProcessor when the Spring context is initialized 
    def onApplicationEvent(event: ContextRefreshedEvent) { 
    autowiredAnnotationBeanPostProcessor = 
     event.applicationContext. 
     getBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME). 
      asInstanceOf[AutowiredAnnotationBeanPostProcessor] 
    } 
} 

object AppConfig { 
    var autowiredAnnotationBeanPostProcessor: AutowiredAnnotationBeanPostProcessor = null 

    def inject(obj: AnyRef) { 
    autowiredAnnotationBeanPostProcessor.processInjection(obj); 
    } 
} 

अब आप किसी भी वस्तु जिसका जीवन चक्र स्प्रिंग द्वारा नियंत्रित नहीं है सुई AppConfig.inject() का उपयोग कर सकते हैं। उदाहरण के लिए, जेपीए इकाइयां, आदि

4

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

@Service 
    object UserRest extends RestHelper { 
     @Autowired 
     @BeanProperty 
     val userRepository: UserRepository = null; 

     ..... 
    } 
<beans> 
     ..... 
     <bean id="userRest" class="com.abc.rest.UserRest" > 
       <!--- this is my attempt to manually wire it ---> 
       <property name="userRepository" ref="userRepository"/> 
     </bean> 
    </beans> 

"var" से "वैल" बदलने अनावश्यक है (वसंत प्रतिबिंब है, जो अचल स्थिति पर ध्यान नहीं देता का उपयोग करता है)। मुझे पूरा यकीन है कि @ बीनप्रोपर्टी भी अनावश्यक है (वसंत अंतर्निहित क्षेत्र को प्रतिबिंबित करेगा)।

3

axtavt के समाधान मेरे लिए काम नहीं किया था, लेकिन अन्य उत्तर से अलग सुझाव के संयोजन मुझे लगता है कि यह सबसे सुरुचिपूर्ण समाधान है:

object User { 
    @Autowired val repo: UserRepository = null 

    def instance() = this 
} 

@Configuration 
class CompanionsConfig { 
    @Bean def UserCompanion = User.instance 
} 

<context:component-scan base-package="your-package" /> 

कुछ नोट:

  • @Configuration को सुनिश्चित करती कि आपके साथी ऑब्जेक्ट उत्सुकता से
  • @ बीन डीफ़ का उपयोग शोर नाम से निपटने के लिए avoids का उपयोग करते हुए स्काला उस वर्ग को देता है जो साथी ऑब्जेक्ट
  • लागू करता है
  • वैल बस ठीक काम करता है, के रूप में डेव ग्रिफिथ ने उल्लेख किया
  • स्काला के @BeanProperty के लिए कोई जरूरत नहीं है, स्प्रिंग स्काला गुण बॉक्स से बाहर (मैं 3.2.2 का उपयोग कर रहा)
0

समझता है के अलावा https://stackoverflow.com/a/8344485/5479289, स्प्रिंग संदर्भ के साथ स्काला पैकेज ऑब्जेक्ट, साथ ही स्काला ऑब्जेक्ट फैक्टरी विधि का उपयोग करना भी संभव है। संकलित पैकेज ऑब्जेक्ट सामान्य जावा क्लास नाम पैकेज है, ताकि आप इसे वसंत संदर्भ में जोड़ सकें। उसके बाद आप इस वस्तु के अंदर सभी वसंत की संभावनाओं होगा, यानी @Autowired, @value, मैनुअल तारों आदि

टेस्ट पैकेज:

package my.module 

package object A { 
    def getInstance = this 

    @Autowired 
    private val b: B = null 
} 

और वसंत संदर्भ एक्सएमएल है:

<beans ...> 
    ... 
    <bean id="a" class="my.module.A.package" factory-method="getInstance"/> 
    ... 
</beans> 
संबंधित मुद्दे