समझ वसंत @Configuration वर्ग


108

इस सवाल का अनुसरण करते हुए स्प्रिंग @Autowired के उपयोग से मैं स्प्रिंग वायरिंग, @Configurationवर्ग के अन्य विकल्प के लिए एक पूर्ण ज्ञान आधार बनाना चाहता था ।

मान लें कि मेरे पास एक स्प्रिंग 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.0.xsd">

  <import resource="another-application-context.xml"/>

  <bean id="someBean" class="stack.overflow.spring.configuration.SomeClassImpl">
    <constructor-arg value="${some.interesting.property}" />
  </bean>

  <bean id="anotherBean" class="stack.overflow.spring.configuration.AnotherClassImpl">
    <constructor-arg ref="someBean"/>
    <constructor-arg ref="beanFromSomewhereElse"/>
  </bean>
</beans>

मैं @Configurationइसके बजाय कैसे उपयोग कर सकता हूं ? क्या इसका कोड पर ही कोई प्रभाव पड़ता है?

जवाबों:


151

XML को माइग्रेट करना @Configuration

@Configurationकुछ ही चरणों में xml को स्थानांतरित करना संभव है :

  1. एक @Configurationएनोटेट वर्ग बनाएँ :

    @Configuration
    public class MyApplicationContext {
    
    }
  2. प्रत्येक <bean>टैग के लिए एनोटेट के साथ एक विधि बनाएं @Bean:

    @Configuration
    public class MyApplicationContext {
    
      @Bean(name = "someBean")
      public SomeClass getSomeClass() {
        return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty
      }
    
      @Bean(name = "anotherBean")
      public AnotherClass getAnotherClass() {
        return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse
      }
    }
  3. आयात करने के लिए beanFromSomewhereElseहमें इसकी परिभाषा करने की आवश्यकता है। इसे एक XML में परिभाषित किया जा सकता है और हम इसका उपयोग करेंगे @ImportResource:

    @ImportResource("another-application-context.xml")
    @Configuration
    public class MyApplicationContext {
      ...  
    }

    यदि बीन को दूसरे @Configurationवर्ग में परिभाषित किया जाता है तो हम @Importएनोटेशन का उपयोग कर सकते हैं :

    @Import(OtherConfiguration.class)
    @Configuration
    public class MyApplicationContext {
      ...
    }
  4. अन्य XML या @Configurationकक्षाओं को आयात करने के बाद , हम अपने संदर्भ में घोषित बीन्स का उपयोग @Configurationकक्षा के लिए एक निजी सदस्य की घोषणा करके कर सकते हैं:

    @Autowired
    @Qualifier(value = "beanFromSomewhereElse")
    private final StrangeBean beanFromSomewhereElse;

    या यह सीधे विधि है जो सेम है कि इस पर निर्भर करता है परिभाषित करता है में पैरामीटर के रूप में उपयोग करने beanFromSomewhereElseका उपयोग कर @Qualifierइस प्रकार है:

    @Bean(name = "anotherBean")
    public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) {
      return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse);
    }
  5. अन्य xml या @Configurationवर्ग से बीन आयात करने के लिए गुण आयात करना बहुत समान है । उपयोग करने के बजाय @Qualifierहम @Valueगुणों के साथ उपयोग करेंगे:

    @Autowired
    @Value("${some.interesting.property}")
    private final String someInterestingProperty;

    यह स्पेल भाव के साथ भी इस्तेमाल किया जा सकता है ।

  6. ऐसे कंटेनरों के रूप में वसंत का इलाज करने की अनुमति देने के लिए हमें इस टैग को संदर्भ में रखकर हमारे मुख्य xml में इसे चिह्नित करने की आवश्यकता है:

    <context:annotation-config/>

    अब आप @Configurationकक्षाओं को ठीक उसी तरह आयात कर सकते हैं जैसे आप एक साधारण बीन बनाएंगे:

    <bean class="some.package.MyApplicationContext"/>

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


इस विधि का उपयोग करने के फायदे और नुकसान

मूल रूप से मुझे कुछ फायदे के कारण एक्सएमएल का उपयोग करने की तुलना में सेम को अधिक आरामदायक घोषित करने की यह विधि मिलती है:

  1. लेखन त्रुटियां - @Configurationकक्षाएं संकलित किए जाते हैं और लिखने की त्रुटियों सिर्फ संकलन अनुमति नहीं दी जाएगी
  2. विफल तेज़ (संकलित समय) - यदि आप एक सेम इंजेक्षन करना भूल जाते हैं तो आप संकलन समय पर विफल हो जाएंगे और रन-टाइम पर टायर के साथ नहीं
  3. IDE में नेविगेट करने में आसान - निर्भरता के पेड़ को समझने के लिए बीन्स के निर्माणकर्ताओं के बीच।
  4. कॉन्फ़िगरेशन स्टार्टअप को आसानी से डीबग करना संभव है

नुकसान कई नहीं हैं क्योंकि मैं उन्हें देखता हूं, लेकिन कुछ ऐसे हैं जो मैं सोच सकता था:

  1. दुरुपयोग - कोड एक्सएमएल की तुलना में दुरुपयोग करने के लिए आसान है
  2. एक्सएमएल के साथ आप उन कक्षाओं के आधार पर निर्भरता को परिभाषित कर सकते हैं जो संकलन समय के दौरान उपलब्ध नहीं हैं लेकिन रन-टाइम के दौरान प्रदान किए जाते हैं। @Configurationकक्षाओं के साथ आपके पास संकलन समय पर उपलब्ध कक्षाएं होनी चाहिए। आमतौर पर यह एक मुद्दा नहीं है, लेकिन ऐसे मामले हैं जो यह हो सकते हैं।

नीचे पंक्ति: XMLs @Configurationऔर एनोटेशन को आपके एप्लिकेशन संदर्भ में संयोजित करना पूरी तरह से ठीक है । स्प्रिंग उस विधि के बारे में परवाह नहीं करता है जिसके साथ एक सेम की घोषणा की गई थी।


2
एक संभावित डाउनसाइड कॉन्फ़िगरेशन का नुकसान है। मान लीजिए कि आपके पास एक वर्ग है जो विकास में कुछ कार्यक्षमता का मजाक उड़ाता है, तो आप इसे UAT वातावरण में किसी अन्य वर्ग के लिए स्वैप करना चाहते हैं। XML का उपयोग करना, फिर इसका विन्यास बदलने और एप्लिकेशन को चलाने / पुनः आरंभ करने की अनुमति देने की बात है। इन नए वर्ग विन्यासों के साथ, वर्गों को नए सिरे से तैयार करना होगा।
जोस

5
@JoseChavez - यह एक महान तर्क है जो मैंने पहले ही कई बार सुना है। और मैंने कुछ सांख्यिकीय शोध करने की कोशिश की, जिसमें मुझे ऐसा कोई ऐप या सिस्टम नहीं मिला जो XML / जार के बाहर का उपयोग करता हो। इसका व्यावहारिक अर्थ यह है कि आपको या तो जार को अनज़िप करना होगा और एक्सएमएल को बदलना होगा (जो मुझे ऐसा कोई नहीं मिला जो ऐसा करता हो) या अपने जार को फिर से बनाएँ (जो मैंने सभी से बात की है उन्होंने कहा है कि उन्होंने अब तक किया है) । इसलिए, निचला रेखा - जैसा कि यह एक विचारणीय तर्क हो सकता है, यह आमतौर पर वास्तविक जीवन में महत्वपूर्ण नहीं है।
एवी

6
यही @Profile एनोटेशन है, और "$ {env.value}" सिंटैक्स, के लिए हैं। @Profile ("someName") के साथ आप केवल प्रोफ़ाइल के सक्रिय होने पर उपयोग के लिए संपूर्ण कॉन्फ़िगरेशन को टैग कर सकते हैं। आपके एप्लिकेशन में .properties (या .yml) फ़ाइल, तो आप स्प्रिंग सेट कर सकते हैं। सक्रिय करें। कोई = कोई नाम, डिफ़ॉल्ट ... इसे पर्यावरण चर पर आधारित गतिशील रूप से सेट करने के लिए, $ {SOME_ENV_VAR} सिंटैक्स का उपयोग वसंत के मान के रूप में करें। active.profiles और पर्यावरण चर सेट करें। वसंत अब जावा कॉन्फिग का उपयोग करने की सलाह देता है - docs.spring.io/spring-boot/docs/current/reference/htmlsingle/…
Jack Viers

विन्यास फाइल में प्रत्येक बीन को विधि के रूप में परिभाषित करने के अलावा और क्या है?
आसिफ मुश्ताक

@AsifMushtaq - आप ऑटोस्कोप सुविधा और प्रत्येक वर्ग का उपयोग कर सकते हैं, @Component @Serviceया इस तरह के अन्य एनोटेशन स्वचालित रूप से एक बीन में किए जाएंगे (लेकिन यह इस सवाल का फोकस नहीं था)
Avi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.