Custom-Autowire-candidate Bohnen im Frühjahr 3
Sagen, ich habe die folgende Struktur mit einem service-Schnittstelle ServiceInterface
und ein paar Komponenten zur Umsetzung: ProductAService
und ProductBService
ich habe auch ein RequestContext
bean, hat eine qualifizierende Eigenschaft, die sagt, dass wir sagen, dass derzeit die Bearbeitung von ProductA oder ProductB. Wie kann dann automatisch Spritzen mit autowiring oder andere annotation der korrekten Umsetzung (ProductAService oder ProductBService) in einigen service, der es benötigt (ServiceThatNeedsServiceInterface
unten).
public interface ServiceInterface {
void someMethod();
}
@Component(name="ProductAService")
public class ProductAService implements ServiceInterface {
@Override public void someMethod() {
System.out.println("Hello, A Service");
}
}
@Component(name="ProductBService")
public class ProductBService implements ServiceInterface {
@Override public void someMethod() {
System.out.println("Hello, B Service");
}
}
@Component
public class ServiceThatNeedsServiceInterface {
//What to do here???
@Autowired
ServiceInterface service;
public void useService() {
service.someMethod();
}
}
@Component
@Scope( value = WebApplicationContext.SCOPE_REQUEST )
public class RequestContext {
String getSomeQualifierProperty();
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Quelle beziehen Ihr Problem, wenn Sie erstellt die ServiceLocatorFactoryBean zurück in der version 1.1.4. Um es zu verwenden benötigen Sie eine Schnittstelle, die ähnlich wie die folgenden:
Müssen Sie den folgenden Abschnitt in Ihre applicationContext.xml
Nun Ihre ServiceThatNeedsServiceInterface sieht ähnlich dem folgenden:
ServiceLocatorFactoryBean zurückkehren wird der gewünschte Dienst auf der Grundlage der RequestContext qualifier.
Neben spring-Annotationen Ihr code ist nicht angewiesen auf den Frühling.
Ich ausgeführt die folgenden unit-test für die oben genannten
In der Konsole-Anzeige
Hallo, Ein Service
Hallo, B-Dienst
Ein Wort der Warnung. In der API-Dokumentation besagt, dass
"Solche service-Locator-Punkte ... wird in der Regel verwendet werden, für die Prototyp-Bohnen, d.h. für die Fabrik-Methoden zurückgeben sollte, eine neue Instanz für jeden Aufruf... Für singleton-beans, direkte setter-oder constructor-injection der Ziel-bean vorzuziehen ist."
Kann ich nicht verstehen, warum dies ein Problem verursachen können. In meinem code gibt es den gleichen service auf zwei Sequenz-Aufrufe serviceThatNeedsServiceInterface.useService();
Finden Sie die Quelle code für mein Beispiel in GitHub
Der einzige Weg, ich kann denken, etwas zu tun, wie das, was Sie suchen, um etwas zu schaffen wie eine FactoryBean dass die Rendite der entsprechenden Umsetzung auf der Grundlage der RequestContext Eigenschaft. Hier ist etwas, ich schlug zusammen, dass das Verhalten, das Sie wollen:
Habe ich ein funktionierendes Beispiel für die Verwendung dieser code auf Github. Sie können Klonen und starten Sie es mit:
Dann besuchen Sie
http://localhost:8080/dynamicallyInjected
zu sehen, die Ergebnis einer Abhängigkeit, undhttp://localhost:8080/dynamicallyInjected?which=bob
andere zu sehen.Ich denke mal, dass Sie es vermisst habe, die Anmerkung, die sagt spring, dass Sie einen benutzerdefinierten Dienst.
Also deine Lösung ist, fügen Sie diese Anmerkungen, bevor Sie die Klasse name:
Und dann kann man auto-Draht, aber um den spezifischen service, den Sie hinzufügen müssen, um die annotation Qualifier() wie folgt:
Oder haben Sie vielleicht hinzufügen, nur eine Anmerkung-Qualifizierer("name eures bean") 🙂
Diese kann Ihnen helfen:
Verwenden
ODER
AutowireCapeableBeanFactory.autowireBean(Objekt existingBean)
AutowireCapeableBeanFactory.autowireBeanProperties(Objekt existingBean, int autowireMode, boolean dependencyCheck)
Ich glaube nicht, können Sie dies mit der Anmerkung, der Grund ist, müssen Sie eine Bohne, die dynamisch zur Laufzeit(vielleicht Ein Dienst oder B service), also @Autowire wird verkabelt sein, bevor die bean in jedem Ort. Eine Lösung ist, kommen Bohnen aus dem Kontext, wenn Sie Sie brauchen.
Sie können setzen else Logik irgendwo in der Klasse als seperate Funktion:
Dies ist die Dynamik und das könnte das sein, was Sie wollen.
Könnten Sie die @Qualifier annotation in Kombination mit Aliase. Sehen Sie ein Beispiel, wie es verwendet wird, laden Sie eine bean-basierend auf einer Eigenschaft hier. Sie ändern könnte, dieser Ansatz und ändern Sie die Eigenschaft/alias in der requestcontext...