it-swarm.com.de

Frühling: @Component vs. @Bean

Ich verstehe, dass @Component Annotation im Frühjahr 2.5 eingeführt wurde, um die Definition von XML-Bean durch Klassenpfad-Scanning zu beseitigen.

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

Wäre es möglich gewesen, die Annotation @Component erneut zu verwenden, anstatt @Bean-Annotation einzuführen? Mein Verständnis ist, dass das Endziel in beiden Fällen die Erstellung von Beans ist.

284
user1396576

@Component und @Bean machen zwei verschiedene Dinge und sollten nicht verwirrt werden.

@Component (und @Service und @Repository) werden zur automatischen Erkennung und automatischen Konfiguration von Beans mithilfe von Classpath-Scans verwendet. Es gibt eine implizite Eins-zu-Eins-Zuordnung zwischen der annotierten Klasse und der Bean (d. H. Eine Bean pro Klasse). Die Verdrahtungskontrolle ist bei diesem Ansatz ziemlich begrenzt, da sie rein deklarativ ist.

@Bean wird verwendet, um explizit eine einzelne Bean zu deklarieren, anstatt dass Spring dies wie oben beschrieben automatisch durchführt. Es entkoppelt die Deklaration der Bean von der Klassendefinition und ermöglicht Ihnen, Beans genau nach Ihren Wünschen zu erstellen und zu konfigurieren.

Zur Beantwortung Ihrer Frage...

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

Sicher, wahrscheinlich; aber sie entschieden sich nicht, da die beiden ziemlich unterschiedlich sind. Der Frühling ist schon verwirrend genug, ohne das Wasser weiter zu trüben.

313
skaffman

@Component Bevorzugt für das Scannen von Komponenten und für die automatische Verdrahtung. 

Wann sollten Sie @Bean verwenden? 

Manchmal ist eine automatische Konfiguration nicht möglich. Wann? Stellen wir uns vor, Sie möchten Komponenten aus Bibliotheken von Drittanbietern verbinden (Sie haben keinen Quellcode, so dass Sie ihre Klassen nicht mit @Component kommentieren können), sodass eine automatische Konfiguration nicht möglich ist. 

Die @Bean Annotation gibt ein Objekt zurück das der Frühling als Bean im Anwendungskontext registrieren soll. Der Körper der Methode trägt die Logik, die für die Erstellung der Instanz verantwortlich ist.

214
MagGGG

Angenommen, ich möchte eine bestimmte Implementierung in Abhängigkeit von einem dynamischen Status. @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();
    }
}

Mit @Component Ist dies jedoch nicht möglich.

152
outdev

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

Der Unterschied ist, dass @Bean auf method anwendbar ist, wohingegen @Component auf types anwendbar ist.

Wenn Sie die Annotation @Bean verwenden, steuern Sie daher die Instanzerstellungslogik im Methodenkörper (siehe Beispiel oben ). Mit @Component Annotation ist das nicht möglich.

62
Nurlan
  1. @Component wird automatisch erkannt und konfiguriert die Beans mithilfe von Classpath-Scanning, während @Bean explizit deklariert eine einzelne Bean ist, anstatt es von Spring automatisch ausführen zu lassen.
  2. @Component entkoppelt nicht die Deklaration des Beans aus der Klassendefinition wobei @Bean entkoppelt die Deklaration des Beans aus der Klassendefinition.
  3. @Component ist ein Annotation auf Klassenebene wobei @Bean ein Annotation auf Methodenebene ist und der Name der Methode als Bean-Name dient.
  4. @Component muss nicht mit der @Configuration verwendet werden -Anmerkung wobei als @Bean-Annotation wird innerhalb der Klasse verwendet werden muss, die mit @Configuration annotiert ist
  5. Wir kann keine Bean erstellen einer Klasse mit @Component, wenn sich die Klasse außerhalb des Spring-Containers befindet, wohingegen wir können eine Bean erstellen einer Klasse mit @Bean, auch wenn die Klasse vorhanden ist außerhalb des Federbehälters.
  6. @Component hat verschiedene Spezialisierungen wie @Controller, @Repository und @Service, wohingegen @Bean keine Spezialisierungen hat.
36
saurabh prakash

@Component Dies ist eine generische Annotation, die auf jede Klasse der Anwendung angewendet werden kann, um sie zu einer durch Federn verwalteten Komponente zu machen (einfach der generische Stereotyp für jede Federverwaltete Komponente). Wenn der Klassenpfad vom Component-scan (@ComponentScan) -Feature der Feder abgetastet wird, werden die mit @Component annotation (innerhalb des angegebenen Pakets) annotierten Klassen identifiziert und die Beans dieser Klassen und das Register erstellt sie im ApplicationContext. @Component ist eine Annotation auf Klassenebene und dient dazu, die Klasse als federverwaltete Komponente und automatisch erkennbare Bean für das Scannen von Klassenpfaden zu erstellen.

wenn Sie mehr über @Component und andere Stereotypanmerkungen erfahren möchten, empfiehlt es sich, diesen Artikel zu lesen.

@Bean wird verwendet, um explizit ein Bean (als Konfigurations-Bean) im Spring IOC - Container zu deklarieren und zu registrieren, das von einer Methode zurückgegeben wird. @Bean ist eine Annotation auf Methodenebene und wird innerhalb einer Klasse verwendet, die mit @Configuration kommentiert wird. Die Annotation @Bean wird einfach verwendet, um die Bean zu registrieren, die von einer Methode als Federkonfigurations-Bean in IOC Container zurückgegeben wird. @Bean ist nur eine Annotation auf Methodenebene und kann nicht mit Klassen und Objektdeklarationen verwendet werden.

@Bean annotation gibt an, dass eine Methode eine Bean erzeugt, die vom Spring-Container verwaltet werden soll.

Um eine Bean zu deklarieren, kommentieren Sie einfach eine Methode mit der Annotation @Bean . Wenn JavaConfig auf eine solche Methode stößt, führt es diese Methode aus und registriert den Rückgabewert als Bean in einem ApplicationContext. Standardmäßig stimmt der Bean-Name mit dem Methodennamen überein. Im Folgenden finden Sie ein einfaches Beispiel für eine @ Bean-Methodendeklaration.

@Configuration
public class ApplicationConfig {

    @Bean
    public User adminUserProfile() {
        return new User("Rami","Nassar");
    }
}

In der ApplicationConfig-Klasse können Sie sehen, dass wir zuerst die Annotation @Configuration verwenden, um Spring mitzuteilen, dass es sich um eine Java-basierte Konfigurationsdatei handelt. Anschließend wird mit der Annotation @Bean eine Spring-Bean und die DI-Anforderungen deklariert .. Die Annotation @Bean entspricht dem Tag, der Methodenname entspricht dem id-Attribut innerhalb des Tags "" . Ich hoffe, dass Sie nach dem Lesen dieses Artikels eine klare Vorstellung von dem tatsächlichen Zweck und der Verwendung von @Bean und @Component -Anmerkungen erhalten haben.

17
Rami Nassar

Wenn Sie das @Component-Tag verwenden, entspricht dies einem POJO (Plain Old Java Object) mit einer Vanilla-Bean-Deklarationsmethode (mit @Bean versehen). Die folgenden Methoden 1 und 2 ergeben beispielsweise dasselbe 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);
}

Mit Methode 2 können Sie Bean-Deklarationen zusammenhalten, es ist etwas flexibler usw. Sie möchten vielleicht sogar eine andere Nicht-Vanilla SomeClass-Bean wie die folgende hinzufügen:

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

Sie können @Bean verwenden, um eine vorhandene Drittanbieter-Klasse für den Kontext Ihrer Spring Framework-Anwendung verfügbar zu machen.

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

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

    return viewResolver;
}

Mit der Annotation @Bean können Sie eine Klasse von Drittanbietern als Spring Bean umbrechen (sie enthält möglicherweise nicht @Component und verwendet möglicherweise nicht Spring). Sobald es mit @Bean umschlossen wurde, ist es ein Singleton-Objekt und in Ihrem Spring Framework-Anwendungskontext verfügbar. Sie können diese Bean jetzt einfach in Ihrer App freigeben/wiederverwenden, indem Sie Dependency Injection und @Autowired verwenden.

Denken Sie also an die Annotation @Bean als Wrapper/Adapter für Klassen von Drittanbietern. Sie möchten die Klassen von Drittanbietern für den Kontext Ihrer Spring Framework-Anwendung verfügbar machen.

Durch die Verwendung von @Bean im obigen Code deklariere ich explizit eine einzelne Bean, da ich das Objekt innerhalb der Methode explizit mit dem Schlüsselwort new erstelle. Ich rufe auch manuell Setter-Methoden der angegebenen Klasse auf. So kann ich den Wert des Präfixfeldes ändern. Daher wird diese manuelle Arbeit als explizite Erstellung bezeichnet. Wenn ich @Component für dieselbe Klasse verwende, hat die im Spring-Container registrierte Bean den Standardwert für das Präfixfeld.

Wenn wir dagegen eine Klasse mit @Component beschriften, müssen wir das new-Schlüsselwort nicht manuell verwenden. Es wird automatisch von Spring gehandhabt.

3
elvis
  • @component und seine Spezialisierungen (@Controller, @service, @repository) ermöglichen die automatische Erkennung von mithilfe von Klassenpfad-Scans. Wenn eine Komponentenklasse wie @Controller, @service, @repository angezeigt wird, wird sie automatisch vom Spring-Framework mit dem Komponentenscan gescannt.
  • @Bean kann dagegen nur verwendet werden, um eine einzelne Bean in einer Konfigurationsklasse explizit zu deklarieren. 
  • @Bean verwendet, um explizit eine einzelne Bean zu deklarieren, anstatt es im Frühling automatisch ausführen zu lassen. Die septate Deklaration von bean aus der Klassendefinition.
  • Kurz gesagt, @Controller, @service, @repository dienen zur automatischen Erkennung und @Bean zum Erstellen von seprate bean aus der Klasse
 - @Controller 
 öffentliche Klasse LoginController 
 {--code--} 

 - @Aufbau
 öffentliche Klasse AppConfig {
 @Bohne
 public SessionFactory sessionFactory () 
 {--code--} 
3
alok

@Bean wurde erstellt, um zu vermeiden, dass Spring und Ihre Geschäftsregeln während der Kompilierung gekoppelt werden. Dies bedeutet, dass Sie Ihre Geschäftsregeln in anderen Frameworks wie PlayFramework oder JEE wiederverwenden können.

Darüber hinaus haben Sie die vollständige Kontrolle darüber, wie Beans erstellt werden, wobei die standardmäßige Spring-Instanzierung nicht ausreicht.

Ich habe einen Beitrag darüber geschrieben.

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

Ich sehe viele Antworten und fast überall ist das erwähnte @Component für Autowiring, bei dem die Komponente gescannt wird und @Bean genau deklariert, dass diese Bean anders verwendet werden soll. Lassen Sie mich zeigen, wie es anders ist.

  • @Bohne

Zuerst ist es eine Annotation auf Methodenebene. Zweitens konfigurieren Sie Beans im Allgemeinen in einem Java-Code (wenn Sie keine XML-Konfiguration verwenden) und rufen sie dann mithilfe der getBean-Methode von ApplicationContext aus einer Klasse auf. mögen

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

class User{
}



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

Es ist eine allgemeine Methode, eine Bohne und keine spezialisierte Bohne mit Anmerkungen zu versehen. Eine Annotation auf Klassenebene, die verwendet wird, um all das Konfigurationsmaterial über die Java- oder XML-Konfiguration zu vermeiden.

Wir bekommen so etwas.

@Component
class User {
}

//to get Bean
@Autowired
User user;

Das ist es . Es wurde nur eingeführt, um alle Konfigurationsschritte zum Instanziieren und Verwenden dieser Bean zu vermeiden.

2
xpioneer

Sie haben zwei Möglichkeiten, Beans zu generieren. Eine besteht darin, eine Klasse mit einer Anmerkung @Component..__ zu erstellen. Die andere besteht darin, eine Methode zu erstellen und sie mit @Bean zu versehen. Für die Klassen, die die Methode mit @Bean enthalten, sollte diese mit @Configuration.__ kommentiert werden. Wenn Sie Ihr Frühlingsprojekt ausführen, scannt die Klasse mit einer @ComponentScan-Anmerkung jede Klasse mit @Component darauf und stellt die Instanz dieser Klasse im Ioc-Container wieder her. Eine andere Sache, die @ComponentScan ausführen würde, ist, die Methoden mit @Bean auszuführen und das zurückgegebene Objekt als Bean ..__ im Ioc-Container wiederherzustellen. Wenn Sie also entscheiden müssen, welche Art von Beans Sie abhängig vom aktuellen Status erstellen möchten, müssen Sie @Bean verwenden. Sie können die Logik schreiben und das gewünschte Objekt zurückgeben. Erwähnenswert ist auch der Name der Methode, wobei @Bean der Standardname von bean ist.

1
Dai Niu