2010-11-19 28 views
0

Je crée une application Web à l'aide de Spring 3 et je souhaite exploiter la puissance de la langue d'expression Spring mais j'ai rencontré un problème. J'ai besoin de définir la valeur d'une propriété sur un de mes beans au résultat d'un appel de méthode sur un autre bean. Je sais que je peux le faire mais le problème est que le résultat de cet appel de méthode peut changer après l'initialisation du bean et j'ai besoin de cette propriété pour refléter le changement. Par exemple:Mise à jour de la valeur d'une propriété Spring bean à l'aide de SpEL

<beans> 
... 
<bean name="guestList" class="java.util.ArrayList"></bean> 

<bean name="party" class="some.custom.class.Party"> 
    <property name="numberOfGuests" value="#{guestList.size()}" /> 
</bean> 
... 
</beans> 

D'après ce que je peux dire, le champ est défini numberOfGuests la première fois le champ party est accessible. Mais après avoir accédé au champ party, le nombre d'invités peut changer et j'ai besoin du champ numberOfGuests pour refléter cela. Est-il possible de réinitialiser le champ numberOfGuests dans mon application chaque fois que j'ai besoin de la valeur mise à jour?

Ceci est juste un exemple et l'accès au bean guestList ne fonctionnera pas directement pour ma situation spécifique.

Répondre

2

si vous définissez votre portée au prototype puis à chaque printemps le temps charge votre haricot devrait recalculer la taille de la liste des invités:

<bean name="party" class="some.custom.class.Party" scope="prototype"> 

Ainsi, party devient prototype mais guestList peut rester un singleton (qui est la portée par défaut).

Il y a un hic cependant: si vous avez un autre haricot, comme partyHost (ce qui est un singleton), et il obtient injecté avec party (qui est un prototype), partyHost aura jamais une autre instance de party, puisque partyHost est un singleton, et obtient seulement les dépendances injectées une fois. Donc, pour que cela fonctionne, tous vos beans qui ont besoin de la taille de la liste des invités mise à jour, et tous les beans qui les référencent, etc. doivent également être des prototypes.

Soit cela, ou vous devriez demander à Spring directement via leur API. Si vous utilisez l'API, vous pouvez l'appeler à tout moment et obtenir une nouvelle instance du prototype de bean, et donc la taille de la liste des invités mise à jour.

applicationContext.getBean("myPrototype"); 

Cependant, il est préférable d'éviter l'API Spring si vous le pouvez. Généralement, les développeurs ne veulent pas être couplés à un cadre DI.

0

L'exemple de # {guestlist.size()} définit uniquement la valeur initiale de la propriété, pas la règle pour la maintenir à jour. En supposant que vous n'utilisez pas le chargement paresseux, Spring instancie les beans gérés par Spring depuis le contexte de l'application au démarrage. À partir de ce moment, c'est au développeur de gérer la mise à jour des valeurs des propriétés.

0

Je suppose la plus simple à faire serait d'injecter la liste (guestList) au haricot et appeler sa méthode .size() manuellement à partir du code Java à chaque fois que vous avez besoin numberOfGuests, à savoir:

package some.custom.class; 

public class Party { 
    private List<?> guestList; 
    // getter & setters 

    public int getNumberOfGuests() { 
    return guestList!=null ? guestList.size() : 0; 
    } 

} 

et ...

<bean name="party" class="some.custom.class.Party"> 
    <property name="guestList" ref="guestList"/> 
</bean> 
+0

c'est certainement la façon de le faire plus simple (et préféré!), mais l'OP a dit: « Ceci est juste un exemple et d'accéder à la fève guestlist directement ne fonctionnera pas pour ma situation. » –

+0

Vous avez raison. Point pris. Nous avons vraiment besoin de plus d'informations alors. Quel est le problème avec l'accès direct au bean 'guestList'? –