2016-09-30 3 views
1

Injizieren Hilfe im Frühjahr hier. In unserem Projekt verwenden wir XML und Annotation-Konfigurationen (Frühjahr 4.1) Vor kurzem habe ich die folgende Aufgabe:Liste der Prototypen in Singleton Bean im Frühjahr

Ich habe eine Liste von Bohnen of scope Prototyp, alle von ihnen die gleiche Schnittstelle implementieren.

Zusätzlich habe ich eine Singleton Bean, die execute Methode hat. Innerhalb der Methode sollte die Bean auf die Liste dieser Prototyp-Beans zugreifen.

Jedes Mal, wenn die Execute-Methode ausgeführt wird, möchte ich den Zugriff auf die verschiedenen Instanzen dieser Prototyp-Beans erhalten). In Singleton habe ich nicht die ganze Liste der Bohnen im Voraus bekannt, so dass ich nur @Autowire die gesamte Sammlung, so dass jede Bean-Implementierung im Anwendungskontext bekannt geladen wird.

interface SomeInterface { 

} 


class PrototypeBean1 implements SomeInterface { 
    ... 
} 

class PrototypeBean2 implements SomeInterface { 
    ... 
} 


class MySingletonBean { 

    @Autowire (????) 
    List<SomeInterface> allPrototypeBeansLoadedIntoTheApplicationContext; 

    public void execute() { 
     // this one is called many times, 
     // so I would like to get different lists of  
     //"allPrototypeBeansLoadedIntoTheApplicationContext" 
     // with different actuals bean upon every invocation 
     // how do I achieve this??? 
    } 

} 

Also meine Frage ist: Was ist der sauberste Weg, um dies zu erreichen? Idealerweise möchte ich eine Lösung bekommen, die völlig von den Feder-Interfaces abgekoppelt ist (wie ApplicationContext/BeanFactory) Ich habe nichts dagegen, hier Aop zu benutzen (die Leistung ist nicht so kritisch), aber ich kann mich nicht wirklich umdrehen eine saubere Frühlingslösung. So wird jede Hilfe geschätzt.

Vielen Dank im Voraus

Antwort

1

Ich habe versucht, ähnliches Ziel mit Frühling zu erreichen und nach entweder ServiceLocatorFactoryBean oder method injection mit Spring docs Lesung (mit @Lookup) kamen und sah vielversprechend aus. Aber nach beiden Versuchen erwies sich beide Ansatz als frustrierend. Keine der beiden Methoden unterstützt das Zurückgeben von Beans in List. Und ich diese Ausnahme bekam:

Keine qualifizierenden Bohne vom Typ ‚java.util.List‘ verfügbar

Offenbar Frühling behandeln den Rückgabetyp als reguläres Objekt.

Also wurde meine Lösung schließlich ein neues Objekt erstellen, um die Liste als Rückgabetyp zu umhüllen.

@Component 
@Scope("prototype") 
public class ProcessorList 
{ 
    private List<Processor> processors; 

    public ProcessorList(List<Processor> processors) 
    { 
     this.processors = processors; 
    } 

    public List<Processor> getProcessors() 
    { 
     return processors; 
    } 

    public void setProcessors(List<ChangeSetProcessor> processors) 
    { 
     this.processors = processors; 
    } 
} 

dann eine Factory-Klasse für die Liste Objekt erstellen:

@Component 
public interface ProcessorFactory 
{ 
    ProcessorList getProcessorList(); 
} 

Dann ServiceLocatorFactoryBean verwenden, um die Fabrik zu registrieren:

@Configuration 
public class MyConfiguration{ 
    @Bean 
    public FactoryBean serviceLocatorFactoryBean() 
    { 
     ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean(); 
     factoryBean.setServiceLocatorInterface(ProcessorFactory.class); 
     return factoryBean; 
    } 

} 

schließlich die Schnittstelle implementieren und stellen Sie sicher, markieren sie alle mit @Scope ("Prototyp")

Jetzt erhalten Sie jedes Mal eine neue Instanz Du verwendest die Fabrikmethode!

Es ist ähnlich zu verwenden Methode Injektion, wenn Sie bevorzugen.

Verwandte Themen