<context:annotation-config>
सेम का उपयोग एनोटेशन को सक्रिय करने के लिए किया जाता है जो पहले से ही आवेदन के संदर्भ में पंजीकृत हैं (कोई फर्क नहीं पड़ता कि उन्हें एक्सएमएल या पैकेज स्कैनिंग के साथ परिभाषित किया गया था)।
<context:component-scan>
यह भी कर सकते हैं कि क्या <context:annotation-config>
करता है, लेकिन <context:component-scan>
एप्लिकेशन संदर्भ में सेम को खोजने और पंजीकृत करने के लिए पैकेजों को भी स्कैन करता है।
मैं अंतर / समानता दिखाने के लिए कुछ उदाहरणों का उपयोग करूँगा।
प्रकार के तीन सेम का एक बुनियादी सेटअप से शुरू A
, B
और C
साथ, B
और C
में इंजेक्ट किया जा रहा है A
।
package com.xxx;
public class B {
public B() {
System.out.println("creating bean B: " + this);
}
}
package com.xxx;
public class C {
public C() {
System.out.println("creating bean C: " + this);
}
}
package com.yyy;
import com.xxx.B;
import com.xxx.C;
public class A {
private B bbb;
private C ccc;
public A() {
System.out.println("creating bean A: " + this);
}
public void setBbb(B bbb) {
System.out.println("setting A.bbb with " + bbb);
this.bbb = bbb;
}
public void setCcc(C ccc) {
System.out.println("setting A.ccc with " + ccc);
this.ccc = ccc;
}
}
निम्नलिखित XML विन्यास के साथ:
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A">
<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />
</bean>
संदर्भ लोड हो रहा है निम्नलिखित उत्पादन का उत्पादन:
creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6
ठीक है, यह अपेक्षित आउटपुट है। लेकिन यह "पुरानी शैली" वसंत है। अब हमारे पास एनोटेशन हैं ताकि एक्सएमएल को सरल बनाने के लिए उन का उपयोग किया जा सके।
सबसे पहले, सेम की तरह गुण bbb
और ccc
संपत्तियों को स्वाहा करता A
है:
package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxx.B;
import com.xxx.C;
public class A {
private B bbb;
private C ccc;
public A() {
System.out.println("creating bean A: " + this);
}
@Autowired
public void setBbb(B bbb) {
System.out.println("setting A.bbb with " + bbb);
this.bbb = bbb;
}
@Autowired
public void setCcc(C ccc) {
System.out.println("setting A.ccc with " + ccc);
this.ccc = ccc;
}
}
यह मुझे XML से निम्न पंक्तियों को हटाने की अनुमति देता है:
<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />
मेरा XML अब इसके लिए सरल हो गया है:
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />
जब मैं संदर्भ को लोड करता हूं तो मुझे निम्नलिखित आउटपुट मिलते हैं:
creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf
ठीक है, यह गलत है! क्या हुआ? मेरी संपत्तियाँ क्यों स्वत: समाप्त नहीं हुईं?
खैर, एनोटेशन एक अच्छी विशेषता है, लेकिन खुद से वे कुछ भी नहीं करते हैं। वे सिर्फ सामान का अनावरण करते हैं। एनोटेशन खोजने और उनके साथ कुछ करने के लिए आपको एक प्रोसेसिंग टूल की आवश्यकता होती है।
<context:annotation-config>
बचाव के लिए। यह एनोटेशन के लिए क्रियाओं को सक्रिय करता है जो इसे उसी एप्लिकेशन संदर्भ में परिभाषित बीन्स पर पाता है जहां स्वयं को परिभाषित किया गया है।
अगर मैं अपने XML को इसमें बदलता हूं:
<context:annotation-config />
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />
जब मैं एप्लिकेशन संदर्भ लोड करता हूं तो मुझे उचित परिणाम मिलता है:
creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b
ठीक है, यह अच्छा है, लेकिन मैंने एक्सएमएल से दो पंक्तियों को हटा दिया है और एक जोड़ा है। यह बहुत बड़ा अंतर नहीं है। एनोटेशन के साथ विचार यह है कि इसे एक्सएमएल को हटाना चाहिए।
तो आइए XML परिभाषाएँ निकालें और उन सभी को एनोटेशन से बदलें:
package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class B {
public B() {
System.out.println("creating bean B: " + this);
}
}
package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class C {
public C() {
System.out.println("creating bean C: " + this);
}
}
package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xxx.B;
import com.xxx.C;
@Component
public class A {
private B bbb;
private C ccc;
public A() {
System.out.println("creating bean A: " + this);
}
@Autowired
public void setBbb(B bbb) {
System.out.println("setting A.bbb with " + bbb);
this.bbb = bbb;
}
@Autowired
public void setCcc(C ccc) {
System.out.println("setting A.ccc with " + ccc);
this.ccc = ccc;
}
}
एक्सएमएल में रहते हुए हम केवल यही रखते हैं:
<context:annotation-config />
हम संदर्भ लोड करते हैं और परिणाम है ... कुछ भी नहीं। कोई फलियां नहीं बनती हैं, कोई फलियां नहीं हैं। कुछ भी तो नहीं!
ऐसा इसलिए है, क्योंकि जैसा कि मैंने पहले पैराग्राफ में कहा था, <context:annotation-config />
केवल आवेदन के संदर्भ में पंजीकृत सेम पर काम करता है। क्योंकि मैंने तीन सेम के लिए एक्सएमएल कॉन्फ़िगरेशन को हटा दिया है, जिसमें कोई बीन नहीं है और <context:annotation-config />
काम करने के लिए कोई "लक्ष्य" नहीं है।
लेकिन यह एक ऐसी समस्या नहीं होगी <context:component-scan>
जिसके लिए काम करने के लिए "लक्ष्य" के लिए एक पैकेज को स्कैन कर सकते हैं। आइए XML एंट्री की सामग्री को निम्न प्रविष्टि में बदलें:
<context:component-scan base-package="com.xxx" />
जब मैं संदर्भ को लोड करता हूं तो मुझे निम्नलिखित आउटपुट मिलते हैं:
creating bean B: com.xxx.B@1be0f0a
creating bean C: com.xxx.C@80d1ff
हम्म्म्म ... कुछ याद आ रहा है। क्यों?
यदि आप कक्षाओं में क्लोजली देखते हैं, तो क्लास A
में पैकेज है, com.yyy
लेकिन मैंने पैकेज <context:component-scan>
का उपयोग करने के लिए निर्दिष्ट किया है, com.xxx
इसलिए यह पूरी तरह से मेरी A
कक्षा से चूक गया और केवल उठाया गया B
और C
जो com.xxx
पैकेज पर हैं।
इसे ठीक करने के लिए, मैं इस अन्य पैकेज को भी जोड़ता हूं:
<context:component-scan base-package="com.xxx,com.yyy" />
और अब हमें अपेक्षित परिणाम मिलेगा:
creating bean B: com.xxx.B@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9
और बस! अब आपके पास XML परिभाषाएँ नहीं हैं, आपके पास एनोटेशन हैं।
अंतिम उदाहरण के रूप में, एनोटेट वर्गों को रखते हुए A
, B
और C
एक्सएमएल में निम्नलिखित जोड़कर, संदर्भ लोड करने के बाद हमें क्या मिलेगा?
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
हम अभी भी सही परिणाम प्राप्त करते हैं:
creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87
यहां तक कि अगर वर्ग के लिए बीन को A
स्कैन करके प्राप्त नहीं किया जाता है, तो प्रसंस्करण उपकरण अभी भी <context:component-scan>
आवेदन के संदर्भ में पंजीकृत सभी बीन्स द्वारा लागू किए जाते हैं , यहां तक कि A
जिसके लिए मैन्युअल रूप से एक्सएमएल में पंजीकृत किया गया था।
लेकिन क्या होगा अगर हमारे पास निम्न XML है, तो क्या हम डुप्लिकेट बीन्स प्राप्त करेंगे क्योंकि हमने दोनों को निर्दिष्ट किया है <context:annotation-config />
और <context:component-scan>
?
<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
नहीं, कोई दोहराव नहीं, हमें फिर से अपेक्षित परिणाम मिलेगा:
creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87
ऐसा इसलिए है क्योंकि दोनों टैग एक ही प्रोसेसिंग टूल को पंजीकृत करते हैं ( <context:annotation-config />
यदि <context:component-scan>
निर्दिष्ट किया गया है तो उसे छोड़ा जा सकता है ) लेकिन स्प्रिंग उन्हें केवल एक बार चलाने का ख्याल रखता है।
यहां तक कि अगर आप कई बार प्रसंस्करण उपकरण खुद को पंजीकृत करते हैं, तो वसंत अभी भी सुनिश्चित करेगा कि वे केवल एक बार अपना जादू करें; यह XML:
<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
<bean id="bla" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla1" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla2" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla3" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
अभी भी निम्नलिखित परिणाम उत्पन्न करेगा:
creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@25d2b2
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87
ठीक है, कि इसके बारे में बलात्कार करता है।
मुझे उम्मीद है कि @Tomasz Nurkiewicz और @ सीन पैट्रिक फ्लॉयड की प्रतिक्रियाओं के साथ-साथ यह जानकारी आपको समझने की ज़रूरत है कि कैसे <context:annotation-config>
और कैसे
<context:component-scan>
काम करना है।