2010-09-28 28 views
94

Diciamo che abbiamo una classe:Come iniettare dipendenze in un oggetto auto-istanziato in primavera?

public class MyClass { 
    @Autowired private AnotherBean anotherBean; 
} 

Poi abbiamo creato un oggetto di questa classe (o qualche altro quadro hanno creato l'istanza di questa classe).

MyClass obj = new MyClass(); 

E 'possibile iniettare ancora le dipendenze? Qualcosa di simile:

applicationContext.injectDependencies(obj); 

(penso Google Guice ha qualcosa di simile)

risposta

141

È possibile farlo utilizzando il metodo autowireBean() di AutowireCapableBeanFactory. Si passa un oggetto arbitrario, e Spring lo tratterà come qualcosa che si è creato da sé, e applicherà i vari frammenti autowiring.

di entrare in possesso del AutowireCapableBeanFactory, appena autowire che:

private @Autowired AutowireCapableBeanFactory beanFactory; 

public void doStuff() { 
    MyBean obj = new MyBean(); 
    beanFactory.autowireBean(obj); 
    // obj will now have its dependencies autowired. 
} 
+0

Buona risposta (+1). C'è anche un secondo metodo in cui puoi influenzare il modo in cui avviene l'autowiring: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html# autowireBeanProperties% 28java.lang.Object,% 20int,% 20boolean% 29 –

+0

Ma cosa succede se ho due oggetti e il primo secondo autowires. In che modo la fabbrica di fagioli autowire tratta le dipendenze nel caso? –

+2

Questo è in realtà un cattivo schema. Se questo è il modo in cui usi veramente MyBean, perché non solo avere il costruttore con AnotherBean come parametro. Qualcosa come: 'code' private @Autowired AnotherBean bean; public void doStuff() {MyBean obj = new MyBean (bean); } 'codice'. Sembra essere come in tutte queste annotazioni, le persone si sentono davvero confuse e non usano il modello di base che era presente nell'SDK di java dal giorno 1. :( – Denis

-6

Non senza alcune soluzioni, come la primavera non sa nulla di questa istanza.

La vera domanda è: perché stai creando istanze di una classe in cui vuoi che le dipendenze vengano iniettate manualmente, piuttosto che lasciare che sia Spring a controllarla? Perché la classe non usa MyClass utilizzando MyClass?

+12

La tua risposta non è corretta, e il tuo "vero problema" è un commento, non una risposta. –

13

È anche possibile contrassegnare i MyClass con annotazione @Configurable:

@Configurable 
public class MyClass { 
    @Autowired private AnotherClass instance 
} 

Poi al momento della creazione si inietta automaticamente le dipendenze . Dovresti anche avere <context:spring-configured/> nel tuo contesto xml dell'applicazione.

+2

Galz666, il tuo metodo sembra molto più pulito per quello che voglio fare. Tuttavia non riesco a farlo funzionare. Non ho file xml e sto usando completamente la configurazione di Java. Esiste un equivalente a ''? – masstroy

+0

vedere http://stackoverflow.com/a/4703781/404615 –

+0

Questa è una soluzione pulita, ma richiede un piccolo sforzo in più: dovresti utilizzare la tessitura a tempo di caricamento come illustrato da iimuhin o aggiungere il compilatore AspectJ al progetto. Il tempo di caricamento come suggerito dal nome causerà costi aggiuntivi in ​​fase di esecuzione. – jsosnowski

0

Ho appena ricevuto la stessa necessità e nel mio caso era già la logica all'interno della classe java non gestibile da Spring che aveva accesso a ApplicationContext. Ispirato allo scafandro. Risolto da:

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory(); 
factory.autowireBean(manuallyCreatedInstance); 
Problemi correlati