Warum kann ich @Autowired
in diesem Fall nicht verwenden ?
@SpringBootApplication
public class Application {
@Autowired
BookingService bookingService;
public static void main(String[] args) {
bookingService.book("Alice", "Bob", "Carol");
}
}
kann aber verwenden @Bean
@SpringBootApplication
public class Application {
@Bean
BookingService bookingService() {
return new BookingService();
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
BookingService bookingService = ctx.getBean(BookingService.class);
bookingService.book("Alice", "Bob", "Carol");
}
}
Sind nicht die beiden Möglichkeiten, BookingService
dasselbe zu generieren ?
java
spring
dependency-injection
zhuochen shen
quelle
quelle
Antworten:
@Bean
und@Autowired
mache zwei sehr unterschiedliche Dinge. Die anderen Antworten hier erklären etwas ausführlicher, aber auf einer einfacheren Ebene:@Bean
sagt Spring 'hier ist eine Instanz dieser Klasse, bitte halte sie fest und gib sie mir zurück, wenn ich frage'.@Autowired
sagt 'Bitte geben Sie mir eine Instanz dieser Klasse, zum Beispiel eine, die ich@Bean
zuvor mit einer Anmerkung erstellt habe'.Ist das sinnvoll? In Ihrem ersten Beispiel bitten Sie Spring, Ihnen eine Instanz von zu geben
BookingService
, aber Sie erstellen nie eine, sodass Spring Ihnen nichts zu geben hat. In Ihrem zweiten Beispiel erstellen Sie eine neue Instanz vonBookingService
, erzählen Spring davon undmain()
fordern dann in der Methode diese zurück.Wenn Sie möchten, können Sie die beiden zusätzlichen Zeilen aus der zweiten
main()
Methode entfernen und Ihre beiden Beispiele wie folgt kombinieren:@SpringBootApplication public class Application { @Autowired BookingService bookingService; @Bean BookingService bookingService() { return new BookingService(); } public static void main(String[] args) { bookingService.book("Alice", "Bob", "Carol"); } }
In diesem Fall gibt die
@Bean
Annotation Spring dasBookingService
und@Autowired
nutzt es.Dies wäre ein etwas sinnloses Beispiel, da Sie alles in derselben Klasse verwenden. Es ist jedoch nützlich, wenn Sie das
@Bean
in einer Klasse und das@Autowired
in einer anderen Klasse definiert haben .quelle
@Bean BookingService bookingService() { return new BookingService(); }
Durch Annotieren wird
@Bean
der Dienst nur als Bean (Art eines Objekts) im Kontext der Frühlingsanwendung registriert. In einfachen Worten, es ist nur Registrierung und sonst nichts.@Autowired BookingService bookingService;
Das Annotieren einer Variablen mit
@Autowired
injiziert eineBookingService
Bean (dh ein Objekt) aus dem Spring-Anwendungskontext.(dh) Die registrierte Bean mit
@Bean
Annotation wird in die mit Annotation versehene Variable eingefügt@Autowired
.Hoffe das klärt deinen Zweifel!
quelle
I.E,registered bean with @Bean will be inject to the variable annotated with @Autowired.
Diese Zeile erweist sich als die Essenz all dessen, worum es in diesen beiden Anmerkungen geht.tolle Antwort von @DaveyDaveDave Im Beispiel statt
@Bean BookingService bookingService() { return new BookingService(); }
Sie können die @ Service-Annotation für die BookingService-Klasse verwenden
quelle
Hier ist ein guter Artikel über @Autowired Annotation: http://www.baeldung.com/spring-autowire
Die Annotation @Autowired kann Ihre injizierbaren Dateien instanziieren, indem Sie @ComponentScan ("Namespace.with.your.components.for.inject") für die Konfigurationsklasse definieren
@Configuration @ComponentScan("com.baeldung.autowire.sample") public class AppConfig {}
Alle Komponenten müssen mit der Annotation @Component gekennzeichnet sein. Es ersetzt die @ Bean-Annotation.
quelle
@Bean dient nur zur Erstellung der Bean durch die Metadatendefinition (entspricht Tag). @Autowired dient zum Injizieren der Abhängigkeit in eine Bean (entspricht dem XML-Tag / Attribut ref).
quelle
Unabhängig davon, welche Klasse Sie mit @Autowire instanziiert haben, können Sie sie innerhalb einer Klasse mit der Annotation @Configuration mithilfe von @Bean für die Methode instanziieren.
Sowohl @Autowire als auch @Bean sind Möglichkeiten, Instanzen einer Klasse zu initialisieren.
Der Unterschied besteht darin, dass Sie mehr Kontrolle über die Initialisierung haben, wenn Sie @Bean zum Instanziieren einer Klasse verwenden. Wenn Sie beispielsweise eine Resilience4J-Leistungsschalterklasse instanziieren und dies innerhalb einer Methode mit @Bean tun, haben Sie die Möglichkeit, die gesamte Konfiguration mithilfe des folgenden Codes festzulegen
@Bean public CircuitBreaker fooCircuitBreaker() { CircuitBreakerConfig.Builder builder = CircuitBreakerConfig.custom(). slidingWindowSize(xxx). failureRateThreshold(xxx). waitDurationInOpenState(xxx)). ignoreException(e -> { if (e instanceof HttpStatusCodeException) { HttpStatusCodeException httpStatusCodeException = (HttpStatusCodeException) e; if (httpStatusCodeException.getStatusCode().is4xxClientError()) { return true; } } return false; }); circuitBreakerRegistry.addConfiguration(xxx, builder.build()); return circuitBreakerRegistry.circuitBreaker(xxx, xxx); }
In einem solchen Fall ist die Verwendung von @Bean offensichtlich der bessere Weg.
quelle