SpEL表达式

SpEL是Spring框架中,运行时查询和操作对象图的语言。通俗的说,SpEL其实就是一个脚本字符串,它可以动态解释执行,操作SpringBean方法,用于获取数据或者执行某些操作。

SpEL最为常见的用法是用于动态装配SpringBean,此外SpEL还有很多花式用法,比如用在自定义注解中,结合AOP,通过SpEL表达式作为配置模板等神奇操作。

XML方式使用SpEL

SpEL是一个可以独立于Spring框架使用的项目,不过我们一般还是集成在Spring框架中使用。使用方式非常简单,下面是一个例子。

<bean id="client" class="com.gacfox.demo.Client">
    <property name="username" value="#{configUtil.username}" />
    <property name="password" value="#{configUtil.password}" />
</bean>

代码中,我们为client这个SpringBean进行装配,但和以往都不相同的是,我们的value属性中,使用了#{}的写法(注意不要和资源配置文件占位符${}弄混),这其实就是调用了SpEL。

#{configUtil.username}:该表达式代表读取名为configUtil的SpringBean中的username属性,如果没有则调用getUsername()方法,通过其返回值装配clientusername属性。下一行类似。

注解方式使用SpEL

除了XML方式,我们也可以使用@Value注解,例子如下:

package com.gacfox.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Client {
    @Value("#{configUtil.username}")
    private String username;
    @Value("#{configUtil.password}")
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Client{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

使用代码执行SpEL表达式

上面介绍了装配Bean时指定SpEL表达式,更高级的用法是通过代码调用SpEL。下面是一个例子:

package com.gacfox.demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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;

/**
 * @author gacfox
 */
public class Main {

    public static void main(String[] args) {
        // 启动Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        EvaluationContext evaluationContext = new StandardEvaluationContext();
        ConfigUtil configUtil = context.getBean("configUtil", ConfigUtil.class);
        evaluationContext.setVariable("configUtil", configUtil);
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression("#configUtil.username");
        System.out.println(expression.getValue(evaluationContext, String.class));
    }
}

注意:使用evaluationContext.setVariable()放入的变量,需要通过#引用

代码虽然行数比较多,但结构十分清晰:

  1. 我们从Spring的ApplicationContext中获取了一个Bean作为变量
  2. 创建SpEL的执行上下文并将configUtil这个对象放进去,解析表达式,自然就能得到其值
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。