2016-04-28 1 views
0

Angenommen, es ist der folgende Code:Dependency Injection durch die Bedingung in der Laufzeit

@RestController 
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) 
class Controller { 

    /* inject here */ 
    public @NonNull GenericService service; 

    public void doo(List<GenericDTO> list, String type) { 
     service.doo(list); 
    } 

} 

class GenericDTO { ... } 
class GenericService { ... } 

class OfferService extends GenericService { ... } 
class OtherService extends GenericService { ... } 

Wenn type von doo Methode "offer" gleich ist, möchte ich eine OfferService Instanz service injizieren. Wenn ich "other" erhalte, muss ich OtherService verwenden, und so weiter. Ist das möglich?

+1

Nun, nein. Dies ist ein einzelnes Feld. Es wird einmal injiziert (wenn es sich um eine Singleton-Bohne handelt). Die Injektionslogik hat keinen Zugriff auf einen Wert, der in einem Methodenaufruf vorhanden ist. Einfach beide Dienste injizieren und ein 'if' verwenden, um zu entscheiden. Erstellen Sie alternativ eine "Map", um den entsprechenden Dienst basierend auf dem Schlüsseltyp auszuwählen. –

Antwort

2

Ich nehme an, alle Ihre Bohnen sind Singletons.

Singleton-Beans werden alle während der Kontextinitialisierung initialisiert und injiziert, was beim Start der Anwendung geschieht, d. Ihre doo Methode (von der ich annahm, dass sie eine Handler-Methode ist) muss noch aufgerufen werden. Es gibt keine Möglichkeit für Spring, die möglichen Werte für den Aufruf einer Methode zu erraten und zu wissen, wie diese Werte in irgendeiner Weise einen Ziel-Injektionspunkt beeinflussen sollen.

Vielleicht könnte ein Proxy helfen und beim Aufruf von doo feststellen, was echte Bohne zu bekommen. Dies ist schwierig, da Sie den Wert von type irgendwie der Komponente zur Verfügung stellen müssen, die die Auflösung tut. Der Frühling kann das nicht out of the box tun. Sie müssen Ihr eigenes Stück dafür schreiben, wahrscheinlich mit Hilfe Ihrer eigenen Scope Implementierung. (Dies ist nicht trivial.)

Die einfachste Lösung ist, beide Dienste und nur if-else/switch auf type injizieren und wählen Sie entsprechend. Oder setzen Sie beide Dienste in eine Map, wobei type der Schlüssel ist.