2010-11-19 12 views
0

Ich erstelle eine Web-App mit Spring 3 und möchte die Kraft der Spring Expression Language nutzen, habe aber ein Problem. Ich muss den Wert einer Eigenschaft für eine meiner Beans auf das Ergebnis eines Methodenaufrufs für eine andere Bean festlegen. Ich weiß, dass ich das tun kann, aber das Problem ist, dass das Ergebnis dieses Methodenaufrufs sich ändern kann, nachdem das Bean initialisiert wurde, und ich brauche diese Eigenschaft, um die Änderung widerzuspiegeln. Zum Beispiel:Aktualisieren Sie den Wert einer Spring-Bean-Eigenschaft mit 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> 

Von dem, was ich sagen kann, ist das numberOfGuests Feld das erste Mal, das party Feld gesetzt zugegriffen wird. Aber nachdem auf das Feld party zugegriffen wurde, kann sich die Anzahl der Gäste ändern und ich brauche das Feld numberOfGuests, um das zu reflektieren. Gibt es eine Möglichkeit, das Feld numberOfGuests in meiner App neu zu initialisieren, wenn der Wert aktualisiert werden muss?

Dies ist nur ein Beispiel und Zugriff auf die guestList Bean direkt funktioniert nicht für meine spezifische Situation.

Antwort

2

Wenn Sie Ihren Umfang zum Prototyp dann jedes Mal Spring Ihren Bean lädt sollte es die Gästeliste Größe neu zu berechnen:

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

So party wird Prototyp aber guestList einen Singleton bleiben kann (das ist der Standardbereich ist).

Es gibt einen Haken aber: wenn Sie eine andere Bohne haben, wie partyHost (die ein Singleton ist), und es wird injiziert mit party (das ist ein Prototyp), partyHost wird nie eine andere Instanz party bekommen, da partyHost a Singleton, und bekommt nur einmal Abhängigkeiten injiziert. Damit dies funktioniert, müssen alle Beans, die die aktualisierte Größe der Gästeliste benötigen, und alle Beans, die auf sie verweisen, usw. auch Prototypen sein.

Entweder das, oder Sie müssen Spring direkt über ihre API fragen. Wenn Sie die API verwenden, können Sie sie jederzeit aufrufen und eine neue Instanz der Prototyp-Bean und damit die aktualisierte Größe der Gastliste abrufen.

applicationContext.getBean("myPrototype"); 

Allerdings ist es besser, die Spring API zu vermeiden, wenn Sie können. Normalerweise möchten Entwickler nicht an ein DI-Framework gekoppelt sein.

0

Das Beispiel von # {guestlist.size()} legt nur den Anfangswert der Eigenschaft fest und nicht die Richtlinie, um sie auf dem neuesten Stand zu halten. Angenommen, Sie verwenden kein Lazy Loading, instanziiert Spring verwaltete Beans aus dem Anwendungskontext beim Start. Ab diesem Zeitpunkt muss der Entwickler die Eigenschaftswerte aktualisieren.

0

Ich würde die einfachste erraten zu tun wäre, um die Liste (guestList) an die Bohne zu injizieren und seine .size() Methode manuell von Java-Code jedes Mal rufen Sie numberOfGuests müssen, das heißt:

package some.custom.class; 

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

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

} 

und ...

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

dies ist definitiv die einfachste (und bevorzugt!) Weg, es zu tun, aber die OP sagte: „Dies ist nur ein Beispiel und den Zugriff auf die Gästeliste Bean wird nicht direkt für meine spezifische Situation arbeiten.“ –

+0

Sie haben Recht. Punkt genommen. Wir brauchen definitiv mehr Informationen. Was ist mit dem direkten Zugriff auf die 'guestList'-Bean falsch? –

Verwandte Themen