2013-10-07 14 views
5

Mam następujących klas:Wybierz których realizacja wstrzykiwać przy starcie wiosną

public interface MyInterface{} 

public class MyImpl1 implements MyInterface{} 

public class MyImpl2 implements MyInterface{} 

public class Runner { 
     @Autowired private MyInterface myInterface; 
} 

Co chcę zrobić, to zdecydować, podczas gdy aplikacja jest już uruchomiony (nie przy starcie), których stosowanie powinno stanowić wstrzyknięty do Runner.

Więc idealnie coś takiego:

ApplicationContext appContext = ... 
Integer request = ... 

Runner runner = null; 
if (request == 1) { 
     //here the property 'myInterface' of 'Runner' would be injected with MyImpl1 
     runner = appContext.getBean(Runner.class) 
} 
else if (request == 2) { 
     //here the property 'myInterface' of 'Runner' would be injected with MyImpl2 
     runner = appContext.getBean(Runner.class) 
} 
runner.start(); 

Jaki jest najlepszy sposób, aby osiągnąć ten cel?

+1

Ten rodzaj celowość z MKOl i Dependency Injection. –

+0

Czy korzystasz z konfiguracji XML lub skanowania komponentów? –

+0

@ToddMurray Wszystkie adnotacje oparte, w ogóle nie XML. – kwh

Odpowiedz

8

implementacje Deklaruję z @Component("implForRq1") i @Component("implForRq2")

Następnie wstrzyknąć im obu i zastosowanie:

class Runner { 

    @Autowired @Qualifier("implForRq1") 
    private MyInterface runnerOfRq1; 

    @Autowired @Qualifier("implForRq2") 
    private MyInterface runnerOfRq2; 

    void run(int rq) { 
     switch (rq) { 
      case 1: runnerOfRq1.run(); 
      case 2: runnerOfRq2.run(); 
      ... 

     } 
    } 

} 

... 

@Autowired 
Runner runner; 

void run(int rq) { 
    runner.run(rq); 
} 
+1

Dobry pomysł. Wielkie dzięki. – kwh

+3

To jest okropny pomysł. Lepiej wywołać jakąś fabrykę, która zwraca pożądaną implementację niż instrukcje rozrzucania w całym miejscu. Zastanów się, co się stanie, gdy musisz dodać trzecią implementację - czy modyfikujesz cały kod, czy po prostu modyfikujesz tylko fabrykę? –

+1

jeśli potrzebuję 3. impl i po prostu zmienię tę klasę ... BTW, teraz, o ile wiem, wiosna (testowane na> = 4.0.x) może wstrzyknąć wszystkie implementacje interfejsu, po prostu zadeklaruj '@Autowired List ' i 'run (int)' zmieni się na: 'void run (int rq) {runners.get (rq) .run(); } '... zobacz przykład tutaj: http://www.nurkiewicz.com/2015/04/spring-injecting-lists-maps-optionals.html. Aby poprawnie porządkować biegaczy implementuj 'Zamówione' w implementacjach' MyInterface' – acc15

Powiązane problemy