2012-05-15 21 views
195

Ich verstehe, dass @Component Annotation im Frühjahr 2.5 eingeführt wurde, um Xml Bean-Definition mithilfe von Classpath-Scanning loszuwerden.Spring: @Component versus @Bean

@Bean wurde im Frühjahr 3.0 eingeführt und kann mit @Configuration verwendet werden, um die XML-Datei vollständig loszuwerden und stattdessen java config zu verwenden.

Wäre es möglich gewesen, die @Component Annotation anstelle der @Bean Annotation zu verwenden? Mein Ziel ist es, in beiden Fällen Bohnen zu kreieren.

+3

Gibt es irgendwo @Bean Kann neben der Konfigurationsklasse verwendet werden? – Willa

+3

Siehe auch [Was ist der Unterschied zwischen '@ Component',' @ Repository' und '@ Service' Annotationen im Frühjahr?] (Http://stackoverflow.com/q/6827752) –

+0

@Willa Ja, gibt es. Das nennt man "Lite-Modus". Und es wird nicht empfohlen. Siehe hier: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-java-basic-concepts – smwikipedia

Antwort

232

@Component und @Bean tun zwei ganz verschiedene Dinge, und sollte nicht verwirrt werden.

@Component (und @Service und @Repository) werden zum automatischen Erkennen und automatischen Konfigurieren von Beans mithilfe des Klassenpfad-Scans verwendet. Es gibt eine implizite Eins-zu-eins-Zuordnung zwischen der annotierten Klasse und der Bean (d. H. Eine Bean pro Klasse). Die Steuerung der Verdrahtung ist bei diesem Ansatz ziemlich begrenzt, da sie rein deklarativ ist.

@Bean wird verwendet, um explizit deklarieren Sie eine einzelne Bean, anstatt Spring tun es automatisch wie oben. Es entkoppelt die Deklaration der Bean von der Klassendefinition und ermöglicht es Ihnen, Beans genau so zu erstellen und zu konfigurieren, wie Sie es auswählen.

Um Ihre Frage zu beantworten ...

wäre es möglich gewesen, die @Component Annotation wieder zu verwenden anstatt @Bean Anmerkung einzuführen?

Sicher, wahrscheinlich; aber sie wählten es nicht, da die beiden ziemlich verschieden sind. Der Frühling ist schon verwirrend genug, ohne das Wasser weiter zu verdrücken.

+2

Also kann ich '@ Component' nur verwenden, wenn Autowired benötigt wird? Es scheint, '@ Bean' kann '@ Autowired' nicht beeinflussen. – Jaskey

+0

Verwenden Sie' @component 'für service-basierte Klassen,' @Bean 'als Fabrik mehr maßgeschneiderte Objekte, zB jdbc datasource –

+1

@Jaskey können Sie' @ Autowired' mit 'verwenden @ Bean' wenn du deine Bean-Klasse mit '@Configuration' versehen hast – starcorn

95

Betrachten wir, ich möchte spezifische Implementierung abhängig von einem dynamischen Zustand. @Bean ist perfekt für diesen Fall.

@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(); 
    } 
} 

Allerdings gibt es keine Möglichkeit, das mit @Component zu tun.

+0

Einfach, klar und prägnant. Ich bevorzuge diese Antwort. – wiseOne

+0

Wie nennen Sie diese Beispielklasse? – PowerFlower

+0

Perfektes Beispiel – HopeKing

86

@Komponente Bevorzugt zum Scannen von Komponenten und zur automatischen Verdrahtung.

Wann sollten Sie @Bean verwenden?

Manchmal ist die automatische Konfiguration keine Option. Wann? Stellen wir uns vor, dass Sie Komponenten aus Bibliotheken von Fremdanbietern verdrahten möchten (Sie haben keinen Quellcode, so dass Sie seine Klassen nicht mit @Component annotieren können), sodass eine automatische Konfiguration nicht möglich ist.

Die @Bean Annotation ein Objekt zurückgibt, die Feder als bean im Anwendungskontext registrieren soll. Der Hauptteil der Methode trägt die Logik, die für das Erstellen der Instanz verantwortlich ist.

+12

Diese Antwort ergibt mehr Sinn für mich. Ich bin neu in Spring Framework. – chandramohan

+0

Ihre Erklärung ist klar.Danke –

+0

Dieser macht Sinn –

31

Beide Ansätze zielen darauf ab, den Zieltyp im Spring-Container zu registrieren.

Der Unterschied besteht darin, dass auf @BeanVerfahren anwendbar ist, während @Component zu Typen anwendbar ist.

Wenn Sie also die Annotation @Bean verwenden, steuern Sie die Instanzerstellungslogik im Methodenhauptteil (siehe example above). Mit @Component Annotation können Sie nicht.

+1

Zum besseren Verständnis des Zieltyps für '@ Bean' und' @ Component' beziehen Sie sich dort Quellcode -> '@ Target's Wert – Bharat

2

Wenn Sie den @Component-Tag verwenden, ist es das gleiche wie eine POJO (Plain Old Java Object) mit einer Vanilleschote Erklärung Methode (kommentierte mit @Bean) mit. Zum Beispiel ergeben die folgenden Methoden 1 und 2 das gleiche Ergebnis.

Methode 1

@Component 
public class SomeClass { 

    private int number; 

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

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

mit einer Bohne für 'theNumber':

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

Methode 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; 
    } 
} 

mit den Bohnen für beide:

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

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

Methode 2 können Sie Bohne Erklärungen zusammen zu halten, es ist ein bisschen flexibler usw. Sie können sogar eine andere Nicht-Vanille-Bohne Someclass wie folgt hinzufügen möchten:

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