2010-01-24 15 views
5

Desidero creare alcuni bean a molla dopo l'avvio in uno schema di fabbrica. Ad esempio, ogni tanto ho del lavoro da fare e ho bisogno di creare un bean di attività (che probabilmente ha dipendenze da altri bean singleton) ed eseguirlo.Creazione di bean su richiesta utilizzando la molla

Possono esserci più parti di lavoro da eseguire contemporaneamente, quindi ogni bean di attività deve essere indipendente (prototipo).

C'è qualche modello comune che le persone utilizzano per raggiungere questo obiettivo?

Come vedo, ho bisogno di interagire con il contenitore/applicationContext in qualche modo, ma non voglio davvero disperdere le iniezioni di applicationContext/beanFactory e le chiamate a getBean ("...") ovunque.

ho pensato a qualcosa di simile (si noti la "fabbrica" ​​è qualcosa che sto immaginando, piuttosto che qualcosa che esiste)

<bean id="myTask" class="MyTask" scope="prototype"> 
    <property name="entityManager" ref=".../> 
    ... 
</bean> 

<bean id="myTaskExecutor" class="MyTaskExecutor"> 
    <property name="taskFactory"> 
    <xxx:factory bean="myTask"/> 
    </property> 
</bean> 

E poi il codice

class MyTaskExecutor 
{ 
    private Factory<MyTask> taskFactory; 

    public void setTaskFactory(Factory<MyTask> taskFactory) 
    { 
    this.taskFactory = taskFactory; 
    } 
} 

E magari un'annotazione versione

class MyTaskExecutor 
{ 
    @Factory(MyTask.class) 
    private Factory<MyTask> taskFactory; 

} 

Forse c'è già qualcosa di simile a quanto sopra? O mi manca qualcosa di fondamentale da qualche parte.

Mi rendo conto che potrei avere un singleton MyTaskFactory e usarlo per creare un'istanza usando "nuovo", ma poi dovrei passare tutti i dipendenti della fabbrica che si sentono in errore.

Quindi credo di riassumere la questione è

Qual è il modo consigliato di creare fagioli primavera prototipo on-demand all'interno di codice dell'applicazione?

Apprezzare qualsiasi input.

risposta

4

Penso che tu stia complicando troppo il problema. Tutto quello che devi fare è scrivere una classe TaskFactory (niente di speciale, nessuna interfaccia o annotazione speciale). TaskFactory verrebbe iniettato con tutti gli altri bean necessari e avrebbe un metodo createTask che crea le attività su richiesta e che passa i riferimenti ai bean Spring richiesti alla nuova attività al momento della creazione. Il codice cliente viene iniettato con TaskFactory e chiama createTask quando richiesto.

Spring stessa non fornisce alcun supporto esplicito per ciò che si sta tentando di fare. Simili di attributi XML factory-method e interfacce FactoryBean sono utili solo per la creazione una tantum di un bean all'interno del suo ambito e se si desidera crearli su richiesta, ovvero scope="prototype", e ciò significa che si utilizza getBean().

modifica: Probabilmente vale la pena sottolineare che i fagioli con scope prototipo non sono realmente ciò per cui è stata progettata Spring. Sì, li supporta, ma utilizzarli non è un'esperienza molto edificante. Se si davvero vuole andare su questa strada, allora vale taking a look at @Configurable. È molto potente, ma non sempre adatto, a causa dei vincoli del classloader di runtime.

+1

Ricevo quello che stai dicendo, ma non mi sembra una soluzione eccezionale (ho detto di avere una fabbrica sopra). Considerare se MyTask ha una dipendenza da altri bean con scope prototipo, ciascuno con le proprie dipendenze. Dovrei fabbricare tutti quelli in fabbrica (e iniettare i loro dipendenti nella mia fabbrica) e passarli a MyTask, oppure farli creare da MyTask, e fare passare la fabbrica in tutti gli altri dipendenti dei bean prototipo. Sembra tutto l'equivalente di non usare la molla per singleton, solo in questo caso è per i fagioli con scope prototipo. –

+0

vedi modifica riguardante '@ Configurable' – skaffman

0

Sto provando a fare una cosa molto simile (Spring 3.0) a questo quindi sarei interessato a sapere come hai risolto questo problema.

Il mio approccio attuale è utilizzare getBean() e ho utilizzato lo scope Singleton predefinito con i miei bean/pojos istatiated Spring. Quindi per ora ho un codice non thread-safe, ma vorrei migliorarlo per essere sicuro anche in futuro.

+0

Ho finito per usare solo BeanFactoryAware sui bean rilevanti e chiamare getBean() come necessario per produrre i miei fagioli prototipo. Sono sicuro che una soluzione di annotazione è interamente fattibile ma ho deciso che sarebbe stato eccessivo per me dato che avevo solo bisogno della funzionalità in circa 5-10 posti, di un'app molto grande. –

Problemi correlati