53 votes

Comment le langage d'expression Spring 3 interagit-il avec des espaces réservés de propriétés?

Le printemps 3 a introduit un nouveau langage d'expression (SpEL) qui peut être utilisé dans de haricots définitions. La syntaxe elle-même est assez bien indiqué.

Ce n'est pas clair, c'est comment, le cas échéant, SpEL interagit avec la propriété de l'espace réservé de la syntaxe, qui était déjà présent dans les versions antérieures. Ne SpEL ont le support de la propriété des espaces réservés, ou dois-je combiner la syntaxe de ces deux mécanismes et de l'espoir qu'ils se combinent?

Permettez-moi de donner un exemple concret. Je veux utiliser la syntaxe de la propriété ${x.y.z}, mais avec l'ajout de "valeur par défaut" de la syntaxe, comme prévu par le elvis opérateur pour gérer les cas où l' ${x.y.z} n'est pas défini.

J'ai essayé les syntaxes suivantes sans succès:

  • #{x.y.z?:'defaultValue'}
  • #{${x.y.z}?:'defaultValue'}

Le premier me donne

Champ ou bien " x " ne peut pas être trouvé sur l'objet de type 'org.springframework.les haricots.usine.config.BeanExpressionContext'

ce qui suggère que SpEL ne reconnaît pas cela comme une propriété de l'espace réservé.

La deuxième syntaxe renvoie une exception en disant que l'espace réservé n'est pas reconnue, de sorte que l'espace réservé résolveur est invoquée, mais est défectueux comme prévu, étant donné que la propriété n'est pas définie.

Les docs ne font aucune mention de cette interaction, de sorte que soit une telle chose n'est pas possible, ou il est sans-papiers.

Quelqu'un a réussi à faire cela?


OK, je viens avec un petit, autonome cas de test pour cela. Tout cela fonctionne comme-est:

Tout d'abord, le haricot définitions:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="
                http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/util    http://www.springframework.org/schema/util/spring-util.xsd
           "> 

    <context:property-placeholder properties-ref="myProps"/>

    <util:properties id="myProps">
        <prop key="x.y.z">Value A</prop>
    </util:properties>

    <bean id="testBean" class="test.Bean">
            <!-- here is where the magic is required -->
        <property name="value" value="${x.y.z}"/> 

            <!-- I want something like this
        <property name="value" value="${a.b.c}?:'Value B'"/> 
            --> 
    </bean>     
</beans>

Ensuite, le trivial bean classe:

package test;

public class Bean {

    String value;

    public void setValue(String value) {
        this.value = value;
    }
}

Et enfin, le cas de test:

package test;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PlaceholderTest {

    private @Resource Bean testBean;

    @Test
    public void valueCheck() {
        assertThat(testBean.value, is("Value A"));
    }
}

Le défi à venir avec un SpEL expression dans les grains de fichier qui me permet de spécifier une valeur par défaut dans les cas où l' ${x.y.z} ne peut pas être résolu, et ce défaut doit être spécifié en tant que partie de l'expression, pas extériorisé dans un autre jeu de propriétés.

27voto

axtavt Points 126632

Pour accéder à un espace réservé de propriété à partir d'une expression SpEL, la syntaxe suivante peut être utilisée: #{'${x.y.z}'} . Cependant, il ne peut pas résoudre votre problème avec l'opérateur elvis et les valeurs par défaut, car il lèverait une exception lorsque ${x.y.z} ne peut pas être résolu.

Mais vous n'avez pas besoin de SpEL pour déclarer les valeurs par défaut des propriétés:

 <context:property-placeholder location="..." properties-ref="defaultValues"/>

<bean id = "defaultValues" class = "org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
        <props>
            <prop key="x.y.z">ZZZ</prop>
        </props>
    </property>
</bean>

<bean ...>
    <property name = "..." value = "${x.y.z}" />
</bean>
 

11voto

Bozho Points 273663

Il semble que vous ayez raté le côlon:

 #{x.y.z?:'defaultValue'}
 

8voto

btpka3 Points 1108

Si vous souhaitez simplement définir la valeur par défaut pour un espace réservé, voir ceci :

    <property name="value" value="${x.y.z:defaultValue}"/> 
 

Si vous souhaitez tester l’interaction entre SpEL et un paramètre fictif, procédez comme suit:

    <!-- set value "77-AA-BB-CC-88" when property "x.y.z" not exist -->
   <property name="value" value="77-#{'AA-${x.y.z:BB}-CC'}-88"/>
 

3voto

Myron Points 21

En fait la Propriété de l'espace Réservé peut résoudre votre problèmes lui-même. I. e. vous pouvez définir des paramètres par défaut explicitement au Printemps contexte, l'aide de la propriété properties. Ensuite, vous pouvez spécifier un emplacement pour les paramètres qui doivent être utilisés, et définir la propriété localOverride de true. Dans de tels cas, toutes les propriétés que l'on trouve dans les ressources externes (indiquée en location de la propriété) remplacent ceux par défaut (défini de façon explicite dans le contexte).

Espère que j'ai aidé.

3voto

micfra Points 1296

Vous devez ajouter ceci pour le faire fonctionner dans votre exemple

 <bean id="testBean" class="elvis.Bean">
        <!-- here is where the magic is required
    <property name="value" value="${x.y.z}"/>
    -->

        <!-- I want something like this -->
    <property name="value" value="#{myProps.get('a.b.c')?:'Value B'}"/>

</bean>
 

Votre approche ne fonctionne pas car Spring tente d’évaluer ${a.b.c} avec un objet a avec membre b avec membre c ce qui entraîne NPE car a n'existe pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X