Surfen im Frühling JavaConfig Referenzdokumentation http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html ich einige verwirrende Teile gefunden ...Frühling JavaConfig inter-Bohne Abhängigkeiten
Unter Abschnitt "5.12.4 Verwendung der @Configuration Anmerkung" heißt es:
„Wenn @Beans Abhängigkeiten voneinander, wird diese Abhängigkeit exprimieren einen anderen so einfach wie mit einem bean Methode aufrufen:
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}
Im obigen Beispiel erhält die Foo-Bean einen Verweis auf Balken über die Konstruktorinjektion. "
Nun, wenn alles staatenlos ist, könnte es nicht viel, aber wenn man die Config oben haben, und dann in der Anwendung tun:
@Autowired
private Foo foo;
@Autowired
private Bar bar;
die Hashcodes der Bohnen Überprüfung stellt sich heraus, , dass Ihr private Variable bar zu einer anderen Instanz von Bar als die von foo verwendet beziehen, was wahrscheinlich ist, nicht, was Sie erwarten, nicht wahr?
Ich würde sagen, das normale Muster eher sein sollte:
@Configuration
public class AppConfig {
@Bean
public Bar bar() {
return new Bar();
}
@Autowired Bar bar;
@Bean
public Foo foo() {
return new Foo(bar);
}
}
Wenn Sie nun beide Bohnen in Ihrer App autowire, werden Sie nur eine einzelne Instanz Bar erstellen.
Fehle ich etwas, oder bin ich richtig, dass die Dokumentation hier flockig ist?
Dann weiter unten, unter Abschnitt „Weitere Informationen darüber, wie Java-basierte Konfiguration arbeiten intern“ es, wie sie dieses Problem versuchen zu „klären“ aussieht:
@Configuration
public class AppConfig {
@Bean
public ClientService clientService1() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientService clientService2() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
}
Jetzt, Leider wird diese Konfiguration nicht einmal zur Laufzeit geladen, weil es zwei Beans vom selben Typ, ClientService, gibt, die keine unterscheidbaren Eigenschaften haben, also erhalten Sie die Ausnahme
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [.....] is defined:
expected single matching bean but found 2
Aber selbst wenn wir das Beispiel etwas zu ändern, und den ersten 2 Bohnen verschiedene Arten geben,
@Bean
public ClientService1 clientService1() {...clientDao()...}
@Bean
public ClientService2 clientService2() {...clientDao()...}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
dies immer noch nicht korrekt ist, da - im Gegensatz zu dem, was dem Text Ansprüche - wir würden noch 3 schaffen unterschiedliche Instanzen von ClientDaoImpl, beim Autowiren aller 3 Beans.
Noch einmal, ich vermisse etwas völlig, oder ist die Dokumentation wirklich so schlecht, wie es mir scheint?
EDIT: Added eine Demo, die das Problem zeigen, werde ich sehen:
bohnen ServiceA, und zwei Bohnen ServiceB1, ServiceB2 dass Konstruktordeklaration einspritzt ServiceA.
Dann zwei Testklassen Config01Test und Config02Test, die mit Ausnahme der Konfigurationen identisch sind. Der erste Test PASSIERT, der zweite versagt wegen Eindeutigkeit.
Warum denken Sie haben Sie verschiedene 'Bar' Objekte zu bekommen? – chrylis
Ich habe einen kleinen Test gemacht und die hashCodes in den Beans überprüft. Sie sind anders. Ich habe das in der obigen Frage geklärt, danke. – Rop
Kannst du ein einfaches laufendes Beispiel auf GitHub veröffentlichen, möglicherweise mit Spring Boot? Ich habe dieses Verhalten noch nie gesehen, und es ist ein Fehler, wenn es wirklich passiert. – chrylis