वसंत: @Component बनाम @ बीन


459

मैं समझता हूं कि @Componentक्लासपैथ स्कैनिंग का उपयोग करके xml सेम परिभाषा से छुटकारा पाने के लिए एनोटेशन को वसंत 2.5 में पेश किया गया था।

@Beanवसंत 3.0 में पेश किया गया था और इसका उपयोग @Configurationपूरी तरह से xml फ़ाइल से छुटकारा पाने के लिए किया जा सकता है और इसके बजाय जावा कॉन्फिग का उपयोग किया जा सकता है ।

क्या @Componentएनोटेशन शुरू करने के बजाय एनोटेशन का फिर से उपयोग करना संभव होगा @Bean? मेरी समझ यह है कि अंतिम लक्ष्य दोनों मामलों में सेम बनाना है।


4
क्या कहीं भी @Bean विन्यास वर्ग के अलावा इस्तेमाल किया जा सकता है?
विस्टा


@Willa हाँ, वहाँ है। यही कहा जाता है Lite mode। और यह अनुशंसित नहीं है। यहाँ देखें: docs.spring.io/spring/docs/current/spring-framework-reference/…
smwikipedia

8
मैं इसे संक्षेप में कहूंगा कि @beanस्प्रिंग बीन के एक अनुकूलन योग्य रिटर्न के साथ एक विधि कह रही है , जबकि @componentएक वर्ग को परिभाषित करता है जिसे बाद में जरूरत पड़ने पर स्प्रिंग IoC इंजन द्वारा लगाया जा सकता है।
सेबास

जवाबों:


433

@Componentऔर @Beanदो काफी अलग चीजें करते हैं, और भ्रमित नहीं होना चाहिए।

@Component(और @Serviceऔर @Repository) करने के लिए उपयोग किया जाता है स्वत: पता लगाएं और classpath स्कैनिंग का उपयोग कर स्वचालित रूप से कॉन्फ़िगर सेम। एनोटेट वर्ग और बीन (यानी प्रति वर्ग एक बीन) के बीच एक-से-एक मैपिंग निहित है। तारों का नियंत्रण इस दृष्टिकोण के साथ काफी सीमित है, क्योंकि यह विशुद्ध रूप से घोषणात्मक है।

@Beanइसका उपयोग स्पष्ट रूप से सिंगल बीन घोषित करने के लिए किया जाता है , बजाय इसके कि स्प्रिंग ऊपर की तरह स्वचालित रूप से करने दे। यह वर्ग परिभाषा से बीन की घोषणा को कम कर देता है, और आपको सेम बनाने और कॉन्फ़िगर करने देता है कि आप कैसे चुनते हैं।

तुम्हारे प्रश्न का उत्तर देने के लिए...

क्या @Componentएनोटेशन शुरू करने के बजाय एनोटेशन का फिर से उपयोग करना संभव होगा @Bean?

ज़रूर, शायद; लेकिन उन्होंने नहीं चुना, क्योंकि दोनों काफी अलग हैं। वसंत पहले से ही भ्रामक है पानी को और अधिक गन्दा किए बिना।


3
इसलिए मैं केवल तभी उपयोग कर सकता हूं @Componentजब ऑटोवार्ड की आवश्यकता हो? ऐसा लगता है @Beanकि प्रभावित नहीं कर सकता है@Autowired
Jaskey

3
सेवा आधारित वर्गों के लिए '@ कॉम्पोनेंट' का उपयोग करें, कारखाने के रूप में '@ बीन' अधिक दर्जी वस्तुओं, उदाहरण के लिए jdbc डेटा स्रोत
Junchen लियू

2
आप उपयोग कर सकते @Jaskey @Autowiredसाथ @Beanयदि आप के साथ अपने सेम वर्ग टिप्पणी किए गए@Configuration
starcorn

6
क्षमा करें, लेकिन मैं आपके स्पष्टीकरण का एक शब्द नहीं समझ सकता। आप इसे स्पष्ट रूप से समझते हैं, इसलिए कृपया आप एक स्पष्ट व्याख्या या उपयुक्त दस्तावेज को इंगित करेंगे?
एलेक्स वर्डेन

13
अब जब मैं अवधारणा को समझ रहा हूं (अन्य लोगों के जवाब पढ़ने से), तो आपका स्पष्टीकरण समझ में आता है। जो मुझे और अधिक बताता है कि आपका स्पष्टीकरण उन सभी के लिए अच्छा नहीं है जो पहले से ही अवधारणाओं को नहीं समझते हैं।
एलेक्स वर्डेन

397

@Component घटक स्कैनिंग और स्वचालित तारों के लिए पसंदीदा।

आपको @ बीन का उपयोग कब करना चाहिए ?

कभी-कभी स्वचालित कॉन्फ़िगरेशन एक विकल्प नहीं है। कब?आइए कल्पना करें कि आप तृतीय-पक्ष पुस्तकालयों से घटकों को तार करना चाहते हैं (आपके पास स्रोत कोड नहीं है इसलिए आप इसकी कक्षाओं को @Component के साथ एनोटेट नहीं कर सकते हैं), इसलिए स्वचालित कॉन्फ़िगरेशन संभव नहीं है।

@Bean एनोटेशन एक वस्तु देता है कि वसंत आवेदन संदर्भ में सेम के रूप में पंजीकृत होना चाहिए। विधि का शरीर उदाहरण बनाने के लिए जिम्मेदार तर्क को सहन करता है।


5
मुझे लगता है कि यह सबसे अधिक समझ में आता है। यदि मैं समझता हूं कि कक्षा के तरीकों (जो कक्षा की वस्तुओं के उदाहरणों को प्राप्त करता है) पर @Componentचलते हुए खुद कक्षाओं में @Beanजाता है।
jocull

182

आइए विचार करें कि मैं कुछ गतिशील स्थिति के आधार पर विशिष्ट कार्यान्वयन चाहता हूं। @Beanउस मामले के लिए एकदम सही है।

@Bean
@Scope("prototype")
public SomeService someService() {
    switch (state) {
    case 1:
        return new Impl1();
    case 2:
        return new Impl2();
    case 3:
        return new Impl3();
    default:
        return new Impl();
    }
}

हालाँकि ऐसा करने का कोई तरीका नहीं है @Component


3
आप उस उदाहरण वर्ग को कैसे कहते हैं?
पावरफ्लॉवर

1
@PowerFower इस विधि को एक विन्यास वर्ग में होना चाहिए, जिसका एनोटेशन किया गया है@Configuration
Juh_

97

दोनों दृष्टिकोण स्प्रिंग कंटेनर में लक्ष्य प्रकार को पंजीकृत करने का लक्ष्य रखते हैं।

अंतर यह है कि विधियों पर@Bean लागू होता है , जबकि प्रकारों पर लागू होता है ।@Component

इसलिए जब आप @Beanएनोटेशन का उपयोग करते हैं तो आप विधि के शरीर में उदाहरण सृजन तर्क को नियंत्रित करते हैं ( ऊपर उदाहरण देखें )। @Componentएनोटेशन के साथ आप नहीं कर सकते।


एक प्रकार क्या है?
जैक फ्रैल

97
  1. @Component auto classpath स्कैनिंग का उपयोग करके सेम का पता लगाता है और कॉन्फ़िगर करता है जबकि @Bean स्पष्ट रूप से सिंगल बीन की घोषणा करता है, बजाय स्प्रिंग को स्वचालित रूप से करने के।
  2. @Component वर्ग परिभाषा से बीन की घोषणा को कम नहीं करता है जहाँ @Bean decouples के रूप में है वर्ग परिभाषा से सेम की घोषणा।
  3. @Component एक क्लास लेवल एनोटेशन है जबकि @Bean एक विधि स्तर एनोटेशन है और विधि का नाम सेम नाम के रूप में कार्य करता है।
  4. @ समुदाय को @ कॉनफिगरेशन एनोटेशन के साथ उपयोग करने की आवश्यकता नहीं है, जहां @ बीन एनोटेशन का उपयोग उस वर्ग के भीतर किया जाना है, जो @ कॉनफिगरेशन के साथ एनोटेट किया गया है
  5. हम एक सेम नहीं बना सकते , एक वर्ग @Component का उपयोग करने का है, तो कक्षा के बाहर वसंत कंटेनर जबकि हम है एक सेम बना सकते हैं अगर वर्ग मौजूद है एक वर्ग @Bean भी उपयोग कर के बाहर वसंत कंटेनर
  6. @Component में @Controller , @Repository और @Service जैसे अलग-अलग स्पेशलाइज़ेशन हैं जबकि @Bean में कोई स्पेशलाइज़ेशन नहीं है

3
4. वास्तव में @ बीन को गैर-विन्यास वर्ग में घोषित किया जा सकता है। यह लाइट मोड के रूप में जाना जाता है
10

1
बिंदु 5 के बारे में। मुझे लगता है कि हम स्प्रिंग कंटेनर के अंदर बीन डालते हैं। तो, हर वर्ग वसंत कंटेनर के बाहर है। मुझे लगता है, बिंदु 5 को पुरस्कृत किया जाना चाहिए
यूगेन

20

मुझे बहुत सारे उत्तर दिखाई देते हैं और लगभग हर जगह इसका उल्लेख @Component ऑटोराइरिंग के लिए है जहां घटक स्कैन किया गया है और @Bean बिल्कुल यह घोषित कर रहा है कि बीन का अलग-अलग तरह से उपयोग किया जाना है। मुझे दिखाते हैं कि कैसे अलग है।

  • @सेम

सबसे पहले इसकी एक विधि स्तर एनोटेशन। दूसरा आप आम तौर पर एक जावा कोड में बीन्स को कॉन्फ़िगर करने के लिए उपयोग करते हैं (यदि आप एक्सएमएल कॉन्फ़िगरेशन का उपयोग नहीं कर रहे हैं) और फिर इसे एप्लीकेशनकॉनटेक्स्ट के गेटबैन विधि का उपयोग करके एक वर्ग से कॉल करें। पसंद

 @Configuration
class MyConfiguration{
    @Bean
    public User getUser(){
        return new User();
    }
}

class User{
}



//Getting Bean 
User user = applicationContext.getBean("getUser");
  • @Component

यह सामान्य तरीके से बीन को एनोटेट करने के लिए है न कि एक विशेष बीन के लिए। एक वर्ग स्तर का एनोटेशन और जावा या एक्सएमएल कॉन्फ़िगरेशन के माध्यम से उस सभी कॉन्फ़िगरेशन सामान से बचने के लिए उपयोग किया जाता है।

हमें कुछ ऐसा मिलता है।

@Component
class User {
}

//to get Bean
@Autowired
User user;

बस । यह सिर्फ उस बीन का त्वरित और उपयोग करने के लिए सभी कॉन्फ़िगरेशन चरणों से बचने के लिए पेश किया गया था।


5
मुझे लगता है कि जब आप @Beanदृष्टिकोण का उपयोग करते हैं तो ApplicationContext से उपयोगकर्ता ऑब्जेक्ट प्राप्त करना आवश्यक नहीं है । आप अभी भी @Autowireसेम प्राप्त करने के लिए उपयोग कर सकते हैं जैसा कि आप के मामले में करेंगे @Component@Beanबस वसंत कंटेनर में बीन जोड़ता है जैसा कि @Componentकरता है। अंतर इस प्रकार है। 1. उपयोग करते हुए @Bean, आप स्प्रिंग कंटेनर में थर्ड पार्टी क्लासेस जोड़ सकते हैं। 2. का उपयोग करते हुए @Bean, आप रन-टाइम पर एक इंटरफ़ेस का वांछित कार्यान्वयन प्राप्त कर सकते हैं (फ़ैक्टरी डिज़ाइन पैटर्न का उपयोग करके)
एंडी

20

आप @Beanअपने स्प्रिंग फ्रेमवर्क एप्लिकेशन के संदर्भ में एक मौजूदा तृतीय-पक्ष क्लास को उपलब्ध कराने के लिए उपयोग कर सकते हैं ।

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

    viewResolver.setPrefix("/WEB-INF/view/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;
}

का उपयोग करके @Beanएनोटेशन , आप तीसरे पक्ष के वर्ग को लपेट सकते हैं (यह नहीं हो सकता है @Componentऔर यह स्प्रिंग का उपयोग नहीं कर सकता है), स्प्रिंग शॉन के रूप में। और फिर एक बार इसका उपयोग करने के बाद @Bean, यह एक सिंगलटन ऑब्जेक्ट के रूप में और आपके स्प्रिंग फ्रेमवर्क एप्लिकेशन संदर्भ में उपलब्ध है। अब आप आसानी से निर्भरता इंजेक्शन और का उपयोग करके अपने ऐप में इस बीन को आसानी से साझा / पुन: उपयोग कर सकते हैं@Autowired

तो सोचो @Bean एनोटेशन थर्ड-पार्टी क्लासेस के लिए एक रैपर / एडॉप्टर है। आप अपने स्प्रिंग फ्रेमवर्क एप्लिकेशन के संदर्भ में तीसरे पक्ष की कक्षाएं उपलब्ध कराना चाहते हैं।

का उपयोग करके @Beanउपरोक्त कोड , मैं स्पष्ट रूप से एक ही बीन घोषित कर रहा हूं क्योंकि विधि के अंदर, मैं स्पष्ट रूप से newकीवर्ड का उपयोग करके ऑब्जेक्ट बना रहा हूं । मैं मैन्युअल रूप से दिए गए वर्ग के सेटर तरीकों को भी कह रहा हूँ। इसलिए मैं उपसर्ग क्षेत्र का मान बदल सकता हूं। इसलिए इस मैनुअल काम को स्पष्ट निर्माण कहा जाता है। यदि मैं @Componentउसी वर्ग के लिए उपयोग करता हूं , तो स्प्रिंग कंटेनर में पंजीकृत बीन में उपसर्ग क्षेत्र के लिए डिफ़ॉल्ट मान होगा।

दूसरी ओर, जब हम किसी वर्ग के साथ एनोटेट करते हैं, तो @Componentहमें newकीवर्ड को मैन्युअल रूप से उपयोग करने की कोई आवश्यकता नहीं है । यह स्प्रिंग द्वारा स्वचालित रूप से नियंत्रित किया जाता है।


1
अच्छा होगा यदि इस उत्तर को इस उदाहरण के साथ अपडेट किया गया कि कैसे सेम का उपयोग किया जाता है
सॉफ्टनर

यदि स्रोत कोड संशोधन की अनुमति नहीं देता है तो आप किसी तृतीय पक्ष वर्ग पर एक @Bean कैसे लपेटेंगे?
veritas

16

जब आप @Componentटैग का उपयोग करते हैं , तो यह वैनिला बीन घोषणा पद्धति के साथ POJO (प्लेन ओल्ड जावा ऑब्जेक्ट) के समान है (साथ एनोटेट @Bean)। उदाहरण के लिए, निम्न विधि 1 और 2 समान परिणाम देगा।

विधि 1

@Component
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

'TheNumber' के लिए सेम के साथ:

@Bean
Integer theNumber(){
    return new Integer(3456);
}

विधि 2

//Note: no @Component tag
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

दोनों के लिए फलियों के साथ:

@Bean
Integer theNumber(){
    return new Integer(3456);
}

@Bean
SomeClass someClass(Integer theNumber){
    return new SomeClass(theNumber);
}

विधि 2 आपको बीन घोषणाओं को एक साथ रखने की अनुमति देता है, यह थोड़ा अधिक लचीला है आदि। आप निम्नलिखित की तरह एक और गैर-वेनिला SomeClass बीन भी जोड़ना चाह सकते हैं:

@Bean
SomeClass strawberryClass(){
    return new SomeClass(new Integer(1));
}

10

आपके पास बीन्स उत्पन्न करने के दो तरीके हैं। एक एनोटेशन के साथ एक वर्ग बनाना है @Component। अन्य एक विधि बनाने और इसके साथ एनोटेट करने के लिए है @Bean। साथ विधि युक्त उन कक्षाओं के लिए @Beanके साथ एनोटेट किया जाना चाहिए @Configuration बार जब आप अपने वसंत परियोजना चलाने के लिए, एक साथ वर्ग @ComponentScanएनोटेशन के साथ हर वर्ग को स्कैन होगा @Componentउस पर, और आईओसी कंटेनर के लिए इस वर्ग के उदाहरण बहाल। एक और बात @ComponentScanयह है कि तरीकों के साथ चल रहा है@Bean और एक बीन के रूप में आईओक कंटेनर में रिटर्न ऑब्जेक्ट को पुनर्स्थापित करें। इसलिए जब आपको यह तय करने की आवश्यकता होती है कि आप वर्तमान स्थिति के आधार पर किस प्रकार की सेम बनाना चाहते हैं, तो आपको उपयोग करने की आवश्यकता है@Bean। आप तर्क लिख सकते हैं और इच्छित वस्तु वापस कर सकते हैं। एक और बात ध्यान देने योग्य है कि विधि का @Beanनाम सेम का डिफ़ॉल्ट नाम है।


6
  • @component और इसके स्पेशलाइजेशन (@Controller, @service, @repository) क्लासथ स्कैनिंग का उपयोग करके ऑटो-डिटेक्शन की अनुमति देते हैं। अगर हमें @Controller, @service जैसे कंपोनेंट क्लास दिखाई देते हैं, तो @repository कंपोनेंट स्कैन का उपयोग करके स्प्रिंग फ्रेमवर्क द्वारा अपने आप स्कैन हो जाएगा।
  • दूसरी ओर @ बीन केवल एक विन्यास वर्ग में स्पष्ट रूप से एक बीन घोषित करने के लिए इस्तेमाल किया जा सकता है।
  • @ बीन स्पष्ट रूप से एक ही बीन की घोषणा करते थे, बजाय वसंत को स्वचालित रूप से करने के। यह वर्ग परिभाषा से बीन की अलग घोषणा करता है।
  • संक्षेप में, @ नियंत्रक, @ सेवा, @ प्रस्ताव ऑटो-डिटेक्शन के लिए हैं और @ बीन क्लास के लिए सेपरेट सीन बनाने के लिए
    - @ कंट्रोलर
    सार्वजनिक वर्ग LoginController 
    {--code--}

    - @Configuration
    सार्वजनिक वर्ग AppConfig {
    @सेम
    सार्वजनिक सत्र सत्र सत्र () 
    {--code--}

3

संकलन समय में वसंत और आपके व्यवसाय के नियमों से बचने के लिए @ बीन बनाया गया था। इसका मतलब है कि आप PlayFramework या JEE जैसे अन्य फ्रेमवर्क में अपने व्यावसायिक नियमों का पुन: उपयोग कर सकते हैं।

इसके अलावा, आपके पास सेम बनाने के लिए कुल नियंत्रण है, जहां यह डिफ़ॉल्ट स्प्रिंग इंस्टेंटेशन के लिए पर्याप्त नहीं है।

मैंने इसके बारे में बात करते हुए एक पोस्ट लिखी।

https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/



1

1. @Component
@Component फंक्शंस के बारे में @Configuration के समान।

वे दोनों इंगित करते हैं कि एनोटेट वर्ग में एक या एक से अधिक फलियाँ हैं जिन्हें पंजीकृत करने की आवश्यकता है Spring-IOC-Container

वर्ग को @ समुदाय द्वारा एनोटेट किया गया है, हम इसे कहते हैं Component of Spring। यह एक अवधारणा है जिसमें कई फलियाँ होती हैं।

Component classउन फलियों को पंजीकृत करने के लिए स्प्रिंग द्वारा ऑटो-स्कैन किए जाने की आवश्यकता है component class

2. के बारे में @
बीन @ बीन का उपयोग विधि के component-classरूप में किया जाता है (जैसा कि ऊपर उल्लेख किया गया है)। यह इंगित करता है कि एनोटेट विधि द्वारा पुनः प्राप्त उदाहरण को पंजीकृत करने की आवश्यकता है Spring-IOC-Container

3. निष्कर्ष
उन दोनों के बीच का अंतर अपेक्षाकृत अप्रिय है, उनका उपयोग किया जाता है different circumstances। सामान्य उपयोग है:

    // @Configuration is implemented by @Component
    @Configuration
    public ComponentClass {

      @Bean
      public FirstBean FirstBeanMethod() {
        return new FirstBean();
      }

      @Bean
      public SecondBean SecondBeanMethod() {
        return new SecondBean();
      }
    }

0

उपरोक्त उत्तरों से अतिरिक्त अंक

मान लीजिए कि हमें एक मॉड्यूल मिला है जो कई ऐप में साझा किया गया है और इसमें कुछ सेवाएं शामिल हैं। प्रत्येक ऐप के लिए सभी आवश्यक नहीं हैं।

यदि उन सेवा वर्गों और अनुप्रयोग में घटक स्कैन पर @Component का उपयोग करें,

हम आवश्यकता से अधिक फलियों का पता लगा सकते हैं

इस मामले में, आपको या तो घटक स्कैन के फ़िल्टरिंग को समायोजित करना होगा या कॉन्फ़िगरेशन प्रदान करना होगा जो अप्रयुक्त फलियां भी चला सकती हैं। अन्यथा, अनुप्रयोग संदर्भ प्रारंभ नहीं होगा।

इस मामले में, @ बीन एनोटेशन के साथ काम करना बेहतर है और केवल उन फलियों को पलटना है,

जो प्रत्येक ऐप में व्यक्तिगत रूप से आवश्यक हैं

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

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