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.
@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.
@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.
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.
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.
@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.
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));
}
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.
- @Controller öffentliche Klasse LoginController {--code--} - @Aufbau öffentliche Klasse AppConfig { @Bohne public SessionFactory sessionFactory () {--code--}
@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.
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");
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.
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.