2010-11-24 14 views
4

J'ai un cas où j'ai un haricot (appelons-le A) qui a besoin d'un autre haricot (B).Obtention d'une instance d'un bean de manière satisfaisante en cours d'exécution

Ce B est extrait d'une méthode statique d'une classe à l'aide de MethodInvokingFactoryBean. Cette méthode statique dépend de l'état du système et fonctionne après le chargement de l'application Web.

Je n'ai besoin d'accéder au B que pendant l'exécution (pas d'interaction dans le constructeur). Comment est-ce que je peux configurer le A pour autofire le bean B et l'initialiser seulement la première fois que A le demande?

L'utilisation de getBean dans le contexte Application est-elle la seule façon?

Merci!

* Modifier - Ajout de quelques xmls :) *

Telle est la définition du haricot B.

<bean id="api" class="com.foo.API"/> 
<bean id="B" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true"> 
     <property name="targetObject" ref="api"/> 
     <property name="targetMethod" value="getFactory"/> 
     <qualifier value="myQualifer"/> 
</bean> 

Telle est la définition du haricot A.

<bean id="resources.someRESTResourceA" class="com.foo.MyRestResource"/>

Je ne peux pas utiliser Autowire pour câbler B dans A car il va l'initialiser (B) sur la construction de A.

La méthode targetMeth de B ne fonctionnera qu'une fois l'application Web initialisée. je peux utiliser ApplicationContext.getBean (« B ») à l'intérieur A, mais ce n'est pas élégant et sera un problème avec les tests unitaires à moins que je fais ce qui suit (qui est pas non plus souhaité):

public BInterface getB() { 
if (b == null) { 
b = ApplicationContext.getBean("B"); 
} 
return b; 
} 
+1

Il serait beaucoup plus facile de comprendre la question si vous pourriez poster un exemple de votre contexte de printemps avec le code de l'exemple de bean. –

+0

Ajouté du code et des xmls .. merci – TheGuyWhoCodes

+0

Salut les gars, je luttais avec ça aussi. Au final, j'ai trouvé la solution à mon problème plutôt simple: il suffit d'implémenter l'interface ApplicationContextAware de Spring qui vous oblige à implémenter la méthode setApplicationContext appelée par Spring. Le printemps met dans l'instance du contexte. Une fois que vous l'avez, vous pouvez simplement obtenir le bean que vous voulez en utilisant appContext.getBean(). Voila. Simple. – Lawrence

Répondre

1

vous devriez paresseusement initialiser le haricot A.

<bean id="A" class="demo.A" lazy-init="true"> 
    <property name="b" ref="B"/> 
</bean> 

vous devez toujours récupérer le grain A partir du conteneur Spring lorsque vous en avez besoin avec la méthode getBean(). Il est facilement accessible avec l'interface ApplicationContextAware.

Si vous autowire bean A dans un autre bean et ce bean est récupéré avant que le bean B est construit, le conteneur Spring va créer bean A au moment où il est injecté en tant que propriété à l'autre bean.

+0

Bean A ne peut pas être paresseux init car c'est un service REST qui est créé au démarrage de l'application web. – TheGuyWhoCodes