14-spring学习-变量操作

表达式所有操作都是可以以变量形式出现的。

观察变量的定义:

package com.Spring.ELDemo;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestSimple2 {
    
    public static void main(String[] args) {
        
        ExpressionParser parser=new SpelExpressionParser();
        Expression exp=parser.parseExpression("#myevl");
        EvaluationContext context=new StandardEvaluationContext();
        context.setVariable("myevl", "hello");
        System.out.println(exp.getValue(context));
    }
}

如果要想设置变量,必须需要依靠“StandardEvaluationContext”类完成,而这个类的子类的构造方法也可以接收一个变量:

public StandardEvaluationContext(Object   rootObject)

这个构造方法表示的是设置根变量的内容:整个变量体系之中 会自动存在一个“#root”的根变量

观察如下:

package com.Spring.ELDemo;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestSimple2 {
    
    public static void main(String[] args) {
        
        ExpressionParser parser=new SpelExpressionParser();
        Expression exp=parser.parseExpression("#root");
        EvaluationContext context=new StandardEvaluationContext("hello");
        System.out.println(exp.getValue(context));
    }
}

如上,没有调用context.setVariable("#root", "hello");,也就是说直接通过了构造方法完成了根变量#root值的传递。

范例:进行比较:

package com.Spring.ELDemo;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestSimple2 {
    
    public static void main(String[] args) {
        
        ExpressionParser parser=new SpelExpressionParser();
        Expression exp=parser.parseExpression("#root=='hello' ?  '你好':'大家好'");
        EvaluationContext context=new StandardEvaluationContext("hello");
        System.out.println(exp.getValue(context));
    }
}

结果:您好。

大部分情况下,最多的时候使用一下自定义变量进行使用,而不是使用根变量。

还能对方法进行引用操作。

方法引用:

范例:将Integer.parseInt()方法设置为myInt()的引用(可以结合之前java知识复习)

package com.Spring.ELDemo;
import java.lang.reflect.Method;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestSimple2 {
    
    public static void main(String[] args) throws Exception {
        
        ExpressionParser parser=new SpelExpressionParser();
        //通过反射找到Integer.parseInt()方法的对象
        Method met=Integer.class.getMethod("parseInt", String.class);
        Expression exp=parser.parseExpression("#myInt('123')");
        //利用StandardEvaluationContext类进行方法的引用注册
        StandardEvaluationContext context=new StandardEvaluationContext();
        //方法进行引用,注册
        context.registerFunction("myInt", met);
        System.out.println(exp.getValue(context));
    }
}

注意以上方法引用步骤。

使用myInt方法在表达式之中相当于调用了Integer.parseInt()方法实现类字符串与int数据的互相转型操作。

还可以调用类中属性,以date类为例,里面有一个getTime()方法,可以将date数据变成lang型数据。

范例:调用属性

package com.Spring.ELDemo;
import java.util.Date;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestSimple2 {
    
    public static void main(String[] args) throws Exception {
        
        ExpressionParser parser=new SpelExpressionParser();
        Expression exp=parser.parseExpression("time");
        //利用StandardEvaluationContext类进行方法的引用注册
        StandardEvaluationContext context=new StandardEvaluationContext(new Date());
        System.out.println(exp.getValue(context));
    }
}

此时将date类的对象设置到了根变量,所以一旦表达式出现了“time”单词就表示,要调用getTime方法

所以需要特别提醒的是,第一个字母不区分大小写。

这种调用本身有风险,此时调用必须有前提:根变量有内容

范例:根变量为空

public class TestSimple2 {
    
    public static void main(String[] args) throws Exception {
        
        ExpressionParser parser=new SpelExpressionParser();
        Expression exp=parser.parseExpression("time");
        //利用StandardEvaluationContext类进行方法的引用注册
        StandardEvaluationContext context=new StandardEvaluationContext();
        System.out.println(exp.getValue(context));
    }
}

根变量为空就会出现异常:

最好解决方式不是增加什么判断,而是使用Groovy安全导航操作,利用Groovy安全运算符避免空异常。

范例:使用“?. ”范围属性

package com.Spring.ELDemo;
import java.util.Date;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestSimple2 {
    
    public static void main(String[] args) throws Exception {
        
        ExpressionParser parser=new SpelExpressionParser();
        Expression exp=parser.parseExpression("#root?.time");
        //利用StandardEvaluationContext类进行方法的引用注册
        StandardEvaluationContext context=new StandardEvaluationContext();
        System.out.println(exp.getValue(context));
    }
}

结果:

如果此时根变量内容为空,那么返回就是null。

以上所有操作变量都是程序中定义的,也可以引用在applicationContext.xml文件中内容。

范例:引用配置中的变量

定义一个Message类

package com.Spring.vo;

public class Message {
    
    private String info;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

在applicationcontext.xml里面配置这个类

    <bean id="msg" class="com.Spring.vo.Message">
        <property name="info" value="hello word"></property>
    </bean>

现在msg对象里面的info属性里面是包含配置内容的,随后希望可以在表达式里面去引用这部分的内容。

引入配置内容,如果要进行导入外部配置,使用“@名称.方法()”

package com.Spring.ELDemo;
import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class TestApplication {
    
    public static void main(String[] args) throws Exception {
        
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");        
        ExpressionParser parser=new SpelExpressionParser();
        //格式,@配置bean的ID.方法()
        Expression exp=parser.parseExpression("@msg.getInfo()");
        StandardEvaluationContext context=new StandardEvaluationContext();
        //将这个配置文件的内容读取交给上下文
        context.setBeanResolver(new BeanFactoryResolver(ctx));
        System.out.println(exp.getValue(context));
    }
}

运行结果:

相当于此时,在外部配置的对象,都可以直接在表达式中使用了。并且利用表达式的语法调用对象所提供的方法。

原文地址:https://www.cnblogs.com/alsf/p/8076480.html