2009-07-20 12 views
6

Ho un'applicazione con più schermate e ogni schermata è selezionata tramite un pulsante. Ogni schermata contiene componenti piuttosto pesanti quindi è importante che solo la schermata di attivazione sia in memoria, tutti gli altri dovrebbero essere disponibili per la raccolta dei dati inutili.Uso di getBean rispetto all'iniezione di metodo in primavera

L'applicazione utilizza molla per la colla e attualmente interruttori schermi usando getBean():

//event handler for a specific button 
public void actionPerformed(Event e) { 
    setScreen((Screen) applicationContext.getBean("screen1")); 
} 

"screen1" è un fagiolo prototipo così una nuova istanza dello schermo viene creata quando viene premuto il pulsante. Inoltre, setScreen() è l'unico posto in cui viene mantenuto un riferimento allo schermo nell'app in modo che la schermata precedentemente attiva sia disponibile per la garbage collection. Non ho ancora provato questo, ma mi aspetto che funzionerà bene - nessuna scienza missilistica qui!

Il problema è - dopo aver letto this page sul motivo per cui getBean() è considerato negativo - Mi chiedo se esiste un modo più idiomatico per ottenere gli stessi risultati rimuovendo la dipendenza da getBean().

Ho esaminato il metodo di iniezione e mi sembra di introdurre la complessità con poco beneficio. È un altro concetto da imparare, più magia, aggiunta dipendenza da CGLIB, ecc. Se voglio davvero rimuovere la dipendenza da Spring, posso semplicemente introdurre un'interfaccia che espone il metodo getBean().

Is getBean() e metodo di iniezione sono le uniche opzioni nel mio caso o ho perso qualcosa?

E se è così, getBean() è davvero così male?

risposta

0

Avete considerato un approccio di fabbrica?

public interface ComponentFactory<T> { 
    T create(); 
} 

public class ScreenFactory implements ComponentFactory<Screen> { 
    @Override 
    Screen create() { ... } 
} 

public class MyApp { 
    private ComponentFactory<Screen> screen1; 

    public void actionPerformed(Event e) { 
    setScreen(screen1.create()); 
    } 

    public void setScreen1(ComponentFactory<Screen> screen1) { 
    this.screen1 = screen1; 
    } 

    private void setScreen(Screen screen) { ... } 
} 

combinato con:

<bean id="screenFactory" class="com.myclass.ScreenFactory"/> 

<bean id="myapp" class="..."> 
    <property name="screen1" ref="screenFactory"/> 
</bean> 

Ovviamente si può auto-wire quanto sopra.

Il problema con ciò che si sta facendo è che entrambi codifica il bean che si sta creando e collega l'implementazione a ApplicationContext. Se hai bisogno di prendere in giro e/o testare le tue app/componenti, questo renderà la tua vita incredibilmente difficile. La soluzione di fabbrica sopra renderà banale.

+0

Quindi nella propria soluzione, getbean() viene richiamato all'interno del metodo factory create(), giusto? –

+0

Non esattamente. È sostituito da un metodo factory, ma è molto più facile prendere in giro l'interfaccia di cui sopra piuttosto che prendere in giro un contesto applicativo. Inoltre è collegabile. In definitiva, si tratta di un'implementazione un po 'più semplice dell'iniezione del metodo di Spring http://static.springsource.org/spring/docs/2.5.x/reference/beans.html # beans-factory-lookup-method-injection – cletus

+0

Vedo, ma da dove viene il metodo factory() per ottenere l'istanza Screen? –

3

Iniezione di setter, iniezione di proprietà o iniezione del costruttore creano un'apposita accoppiata che è molto più facile da testare attraverso il beffeggiamento. Inoltre impedisce a qualsiasi classe di avere dipendenze dirette sulle classi Spring (o altre classi IoC). Finisce semplicemente per essere una soluzione globale più pulita quando non devi chiamare manualmente getBean().

Penso che dovresti sentirti a tuo agio con la nozione di configurazione delle dipendenze. La "magia" non è affatto magica ed è solo qualcosa a cui ti sentirai a tuo agio mentre la usi.

+0

Mi riferisco all'iniezione del metodo usando il tag lookup-method che IMO è diverso dall'iniezione delle dipendenze "standard": è una funzione separata e basata su AOP (e quindi CGLIB) e che cosa fornisce a una fabbrica (che il cletus ha dimostrato?) –

+0

La factory isolerà la tua dipendenza da Spring, ma diventa quello che penso sia solo un codice non necessario da mantenere. Cosa c'è di sbagliato in AOP? AOP è solo un dettaglio di implementazione di come Spring fa DI. – geofflane

0

Se si desidera semplicemente sbarazzarsi di getBean, considerare l'utilizzo di ServiceLocatorFactoryBean. Ma quanto bene ciò funzioni per te può dipendere da dove proviene la stringa "screen1" nella tua applicazione.

Problemi correlati