@Resource बनाम @Autowired


380

कौन सा एनोटेशन, @Resource ( jsr250 ) या @Autowired (स्प्रिंग-विशिष्ट) मुझे DI में उपयोग करना चाहिए?

मैंने अतीत में दोनों का सफलतापूर्वक उपयोग किया है, @Resource(name="blah")और@Autowired @Qualifier("blah")

मेरी वृत्ति @Resourceटैग के साथ रहना है क्योंकि यह jsr लोगों द्वारा पुष्टि की गई है।
किसी को भी इस पर मजबूत विचार है?


FYI करें - मैंने 'अपडेट' को हटा दिया है, इसे एक अलग प्रश्न के रूप में पूछा जाना चाहिए था। इस टिप्पणी के अनुसार, "यह संपादन पोस्ट के मूल इरादे से विचलित करता है। यहां तक ​​कि संपादन जो कठोर बदलाव करना चाहिए, पोस्ट के मालिक के लक्ष्यों को संरक्षित करने का प्रयास करना चाहिए"
mlo55

जवाबों:


194

वसंत पूर्व 3.0 में यह कोई फर्क नहीं पड़ता कि कौन सा है।

वसंत 3.0 में मानक ( JSR-330 ) एनोटेशन के लिए समर्थन है @javax.inject.Inject- के संयोजन के साथ इसका उपयोग करें @Qualifier। ध्यान दें कि वसंत अब @javax.inject.Qualifierमेटा-एनोटेशन का भी समर्थन करता है :

@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}

तो आपके पास हो सकता है

<bean class="com.pkg.SomeBean">
   <qualifier type="YourQualifier"/>
</bean>

या

@YourQualifier
@Component
public class SomeBean implements Foo { .. }

और तब:

@Inject @YourQualifier private Foo foo;

यह स्ट्रिंग-नामों का कम उपयोग करता है, जिन्हें गलत तरीके से रखा जा सकता है और बनाए रखना मुश्किल होता है।


मूल प्रश्न के रूप में: दोनों, एनोटेशन की किसी भी विशेषता को निर्दिष्ट किए बिना, प्रकार द्वारा इंजेक्शन प्रदर्शन करते हैं। अंतर यह है:

  • @Resource आपको इंजेक्शन वाले बीन का नाम निर्दिष्ट करने की अनुमति देता है
  • @Autowired आपको इसे गैर-अनिवार्य के रूप में चिह्नित करने की अनुमति देता है।

यह एक मूर्खतापूर्ण सवाल की तरह देख सकते हैं, लेकिन जब आप इंजेक्शन की इस शैली का उपयोग करें, आप के लिए एक सार्वजनिक सेटर की जरूरत है fooया में एक निर्माता SomeBeanएक साथ Fooपरम?
स्नेक

@Snekse - मेरा उत्तर समझे: stackoverflow.com/questions/3536674/…
स्नेक

नहीं। आप किसी भी जरूरत नहीं है कि सिर्फ मैदान। (वसंत इसे प्रतिबिंब के माध्यम से आबाद करता है)
Bozho

@Bozho यह उत्तर वास्तव में @Resourceऔर के बीच अंतर नहीं दिखाता है @Autowired, वास्तविक उत्तर @Ichthyo द्वारा पोस्ट किया गया है, मुझे लगता है कि यह अपडेट होना चाहिए।
बोरिस ट्रेखोव

1
हाँ। वास्तव में मैं कभी-कभी दृष्टिकोण का एक बेहतर विकल्प प्रदान करके प्रश्नों का उत्तर देता हूं। लेकिन मैंने नीचे दिए मूल प्रश्न का उत्तर पूर्णता के लिए शामिल किया
Bozho

508

दोनों @Autowired(या @Inject) और @Resourceसमान रूप से अच्छी तरह से काम करते हैं। लेकिन एक वैचारिक अंतर या अर्थ में अंतर है

  • @Resourceमतलब मुझे नाम से एक ज्ञात संसाधन मिलता है । नाम एनोटेट सेटर या फ़ील्ड के नाम से निकाला जाता है, या इसे नाम-पैरामीटर से लिया जाता है।
  • @Injectया टाइप करके उपयुक्त अन्य घटक@Autowired में तार लगाने की कोशिश करें ।

तो, मूल रूप से ये दो बिल्कुल अलग अवधारणाएँ हैं। दुर्भाग्य से स्प्रिंग-इंप्लीमेंटेशन @Resourceमें एक अंतर्निर्मित फॉलबैक होता है, जो कि रिज़ॉल्यूशन बाई-नेम में विफल होने पर किक करता है। इस मामले में, यह वापस @Autowiredधर्म-प्रकार के संकल्प से गिरता है। हालांकि यह गिरावट सुविधाजनक है, IMHO यह बहुत भ्रम का कारण बनता है, क्योंकि लोग वैचारिक अंतर से अनजान होते हैं और @Resourceटाइप-आधारित ऑटोवेयरिंग के लिए उपयोग करते हैं ।


81
हां, यह एक स्वीकृत उत्तर होना चाहिए। उदाहरण के लिए यदि आपके पास एक @Resourceएनोटेट फ़ील्ड है, और फ़ील्ड नाम कंटेनर में बीन की आईडी से मेल खाता है, तो स्प्रिंग फेंक देगा org.springframework.beans.factory.BeanNotOfRequiredTypeExceptionयदि उनके प्रकार अलग-अलग हैं - ऐसा इसलिए है क्योंकि बीन्स को पहले @Resourceएनोटेशन में नाम से मिलान किया जाता है , न कि प्रकार से। लेकिन अगर संपत्ति का नाम बीन के नाम से मेल नहीं खाता है, तो स्प्रिंग उन्हें टाइप करके तार देगा।
बोरिस ट्रेखोव

जब आप एक साधारण MAP का उपयोग करने का प्रयास करते हैं, तो आप इस दो के बीच अंतर बताने वाली दूसरी पोस्ट का उल्लेख कर सकते हैं। stackoverflow.com/questions/13913752/…
Anver Sadhat

4
+1 वास्तव में स्वीकार किए गए उत्तर के रूप में केवल एक पूरी तरह से अलग "सर्वोत्तम अभ्यास" की सिफारिश करने के बजाय प्रश्न का उत्तर देने के लिए। मुझे यह ब्लॉग पोस्ट भी मिला, जिसमें तीनों एनोटेशन शैलियों के साथ कई सामान्य परिदृश्यों के परिणाम दिखाई देते हैं, सहायक: blogs.sourceallies.com/2011/08/…
जूल्स

1
पाठक के लिए, कृपया @Jules द्वारा बताए गए लेख का एक सारांश यहां देखें: stackoverflow.com/a/23887596/363573
Stephan

3
इसका एक निहितार्थ है: जब आप एक मानचित्र / सूची बीन इंजेक्ट करना चाहते हैं, तो @Autowireकाम नहीं कर सकता। आपको @Resourceउस स्थिति में उपयोग करना होगा ।
रिकार्डो वैन डेन ब्रोक

76

प्राथमिक अंतर है, @Autowiredएक स्प्रिंग एनोटेशन है। जबकि @ResourceJSR-250 द्वारा निर्दिष्ट किया गया है, जैसा कि आपने खुद बताया। तो बाद वाला जावा का हिस्सा है जबकि पूर्व स्प्रिंग विशिष्ट है।

इसलिए, आप सही अर्थों में यह सुझाव दे रहे हैं। मैंने पाया कि लोग इसके @Autowiredसाथ उपयोग करते हैं @Qualifierक्योंकि यह अधिक शक्तिशाली है। कुछ फ्रेमवर्क से कुछ अन्य में ले जाना बहुत ही असंभाव्य माना जाता है, यदि मिथक नहीं है, खासकर वसंत के मामले में।


7
+1, क्योंकि @Autowiredके साथ @Qualifierवास्तव में है JSR मानक से अधिक शक्तिशाली @Resourceएनोटेशन (साथ उदाहरण के लिए वैकल्पिक निर्भरता के बारे में सोच @Autowired(required=false)। आप के साथ ऐसा नहीं कर सकते @Resource)
स्टीफन Haberl

70

मैं इस प्रश्न के उत्तर पर @ जूल्स की एक टिप्पणी पर जोर देना चाहूंगा । टिप्पणी एक उपयोगी लिंक लाती है: स्प्रिंग इंजेक्शन @Resource, @Autowired और @Inject के साथ । मैं आपको इसे पूरी तरह से पढ़ने के लिए प्रोत्साहित करता हूं, हालांकि यहां इसकी उपयोगिता का त्वरित सारांश है:

एनोटेशन सही कार्यान्वयन का चयन कैसे करते हैं?

@Autowired तथा @Inject

  1. प्रकार से मेल खाता है
  2. क्वालिफायर द्वारा प्रतिबंधित
  3. नाम से मेल खाता है

@Resource

  1. नाम से मेल खाता है
  2. प्रकार से मेल खाता है
  3. क्वालिफायर द्वारा प्रतिबंधित (यदि मैच नाम से पाया जाता है)

मुझे अपनी बीन्स को इंजेक्ट करने के लिए किस एनोटेशन (या संयोजन) का उपयोग करना चाहिए?

  1. स्पष्ट रूप से अपने घटक का नाम [@Component ("beanName")]

  2. विशेषता के @Resourceसाथ उपयोग करें name[@Resource (नाम = "beanName")]

मुझे क्यों नहीं उपयोग करना चाहिए @Qualifier?

@Qualifierजब तक आप समान सेम की सूची नहीं बनाना चाहते, एनोटेशन से बचें । उदाहरण के लिए आप एक विशिष्ट @Qualifierएनोटेशन के साथ नियमों के एक सेट को चिह्नित करना चाह सकते हैं । यह दृष्टिकोण नियम वर्गों के एक समूह को एक सूची में इंजेक्ट करना सरल बनाता है जो डेटा को संसाधित करने के लिए उपयोग किया जा सकता है।

क्या सेम इंजेक्शन मेरे कार्यक्रम को धीमा कर देता है?

घटकों के लिए विशिष्ट पैकेज स्कैन करें [context:component-scan base-package="com.sourceallies.person"]। हालांकि यह अधिक component-scanकॉन्फ़िगरेशन में परिणाम देगा, यह मौका कम कर देता है कि आप अपने स्प्रिंग संदर्भ में अनावश्यक घटकों को जोड़ देंगे।


संदर्भ: स्प्रिंग इंजेक्शन @Resource, @Autowired और @Inject के साथ


39

यह मुझे स्प्रिंग 3.0.x संदर्भ नियमावली से मिला है : -

टिप

यदि आप नाम से एनोटेशन-संचालित इंजेक्शन व्यक्त करने का इरादा रखते हैं, तो मुख्य रूप से @Autowired का उपयोग न करें, भले ही तकनीकी रूप से @Qualifier मानों के माध्यम से सेम नाम का उल्लेख करने में सक्षम हो। इसके बजाय, JSR-250 @Resource एनोटेशन का उपयोग करें, जो कि मिलान प्रक्रिया के लिए अप्रासंगिक होने के साथ अपने विशिष्ट नाम से एक विशिष्ट लक्ष्य घटक की पहचान करने के लिए शब्दार्थ रूप से परिभाषित है।

इस शब्दार्थिक अंतर के विशिष्ट परिणाम के रूप में, बीन्स जो खुद को एक संग्रह या मानचित्र प्रकार के रूप में परिभाषित करते हैं, उन्हें @Autowired के माध्यम से इंजेक्ट नहीं किया जा सकता है, क्योंकि टाइप मिलान उनके लिए ठीक से लागू नहीं है। इस तरह के बीन्स के लिए @Resource का उपयोग करें, विशिष्ट संग्रह या अद्वितीय नाम से बीन का जिक्र करें।

@Autowired पैरामीटर स्तर पर क्वालीफायर एनोटेशन के माध्यम से संकीर्ण करने की अनुमति देते हुए, फ़ील्ड, कंस्ट्रक्टर और बहु-तर्क विधियों पर लागू होता है। इसके विपरीत, @Resource केवल फ़ील्ड और बीन प्रॉपर्टी सेटर विधियों के लिए एक ही तर्क के साथ समर्थित है। परिणाम के रूप में, क्वालीफायर के साथ छड़ी अगर आपका इंजेक्शन लक्ष्य एक निर्माता या एक बहु-तर्क विधि है।


वर्तमान संस्करण के लिए docs.spring.io/spring/docs/current/spring-framework-reference/… (टिप अपडेट किया गया था) देखें
Lu55

27

अगर आप भविष्य में कुछ अन्य DI का उपयोग करना चाहते हैं तो @Autowired + @Qualifier केवल स्प्रिंग DI के साथ काम करेगा, अच्छा विकल्प है।

अन्य अंतर जो मुझे बहुत महत्वपूर्ण लगा, वह है @Qualifier डायनामिक बीन वायरिंग का समर्थन नहीं करता है, क्योंकि @Qualifier प्लेसहोल्डर का समर्थन नहीं करता है, जबकि @Resource इसे बहुत अच्छी तरह से करता है।

उदाहरण के लिए: यदि आपके पास इस तरह कई कार्यान्वयन के साथ एक इंटरफ़ेस है

interface parent {

}
@Service("actualService")
class ActualService implements parent{

}
@Service("stubbedService")
class SubbedService implements parent{

}

@Autowired & @Qualifier के साथ आपको विशिष्ट बाल कार्यान्वयन सेट करना होगा

@Autowired
@Qualifier("actualService") or 
@Qualifier("stubbedService") 
Parent object;

जो प्लेसहोल्डर को प्रदान नहीं करता है, जबकि @Resource के साथ आप विशिष्ट चाइल्ड कार्यान्वयन को इंजेक्ट करने के लिए प्लेसहोल्डर और संपत्ति फ़ाइल का उपयोग कर सकते हैं

@Resource(name="${service.name}")
Parent object;  

जहाँ service.name प्रॉपर्टी फ़ाइल के रूप में सेट है

#service.name=actualService
 service.name=stubbedService

आशा है कि किसी की मदद करता है :)


16

ये दोनों समान रूप से अच्छे हैं। संसाधन का उपयोग करने का लाभ भविष्य में है यदि आप वसंत के अलावा किसी अन्य डीआई ढांचे को चाहते हैं, तो आपके कोड परिवर्तन बहुत सरल होंगे। स्वतः कोड का उपयोग करके स्प्रिंग्स डि के साथ कसकर युग्मित किया गया है।


17
ऐसा कभी नहीं होगा। और यहां तक ​​कि अगर यह किया - एनोटेशन नामों पर एक खोज / प्रतिस्थापित करना आपकी समस्याओं का कम से कम होना है।
डैनियल अलेक्सियस

13

जब आप इन दो एनोटेशन के आधार वर्गों से गंभीर रूप से विश्लेषण करेंगे। आपको निम्नलिखित अंतरों का एहसास होगा।

@AutowiredAutowiredAnnotationBeanPostProcessor निर्भरता को इंजेक्ट करने के लिए उपयोग करता है।
@Resourceका उपयोग करता हैCommonAnnotationBeanPostProcessorनिर्भरता को इंजेक्ट करने के लिए है।

भले ही वे अलग-अलग पोस्ट प्रोसेसर कक्षाओं का उपयोग करते हैं, लेकिन वे सभी लगभग समान व्यवहार करते हैं। मतभेद गंभीर रूप से उनके निष्पादन पथ में निहित हैं, जिन्हें मैंने नीचे प्रकाश डाला है।

@Autowired / @Inject

1. प्रकार के
आधार पर 2. पात्रता के
आधार पर जिले 3. नाम से नमूने

@Resource

नाम से
1.Matches 2. प्रकार द्वारा
नमूने 3. क्वालिफायर द्वारा जिलों (नजरअंदाज अगर मैच नाम से पाया जाता है)


6

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

स्प्रिंग के साथ 4.3+ @Autowiredभी ऐसा करने में सक्षम है।


2

@Resourceअक्सर JNDI के माध्यम से परिभाषित उच्च-स्तरीय वस्तुओं द्वारा उपयोग किया जाता है। @Autowiredया @Injectअधिक आम बीन्स द्वारा उपयोग किया जाएगा।

जहां तक ​​मुझे पता है, यह एक विनिर्देश नहीं है, न ही एक सम्मेलन भी। यह अधिक तार्किक तरीका है मानक कोड इन एनोटेशन का उपयोग करेगा।


0

यहां एक नोट के रूप में: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContextऔर एनोटेशन के साथ काम SpringBeanAutowiringSupport.processInjectionBasedOnServletContext नहीं करता है@Resource । तो, अंतर हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.