专业的JAVA编程教程与资源

网站首页 > java教程 正文

玩转Spring中强大的spel表达式!_spring的scope有几种

temp10 2025-09-24 03:46:38 java教程 2 ℃ 0 评论

SpEL(Spring Expression Language)是 Spring 框架中一个功能强大的表达式语言,可在运行时查询和操作对象图。它支持丰富的语法和特性,能极大提升代码的灵活性和可维护性。下面从基础到高级,全面介绍 SpEL 的用法:

1. 基础表达式

SpEL 可以通过@Value注解、XML 配置或编程方式使用。

玩转Spring中强大的spel表达式!_spring的scope有几种


import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

public class SpelExample {
    public static void main(String[] args) {
        // 实例化表达式解析器
        ExpressionParser parser = new SpelExpressionParser();

        // 处理字面量表达式
        Expression exp = parser.parseExpression("'Hello SpEL'");
        // 获取表达式的值
        String message = (String) exp.getValue(); // "Hello SpEL"

        // 解析数学表达式并获取其值
        int sum = parser.parseExpression("1 + 2").getValue(Integer.class); // 3

        // 解析布尔表达式并获取其值
        boolean isTrue = parser.parseExpression("true and false").getValue(Boolean.class); // false
    }
}

2. 对象属性与方法调用

SpEL 支持访问对象属性、调用方法,甚至使用内置函数。


public class User {
    // 私有成员变量,存储用户姓名,初始化为 "John"
    private String name = "John";
    // 私有成员变量,存储用户年龄,初始化为 30
    private int age = 30;

    // 获取用户姓名的公共方法
    public String getName() {
        return name;
    }

    // 获取用户年龄的公共方法
    public int getAge() {
        return age;
    }

    // 用于生成问候语的公共方法,接收一个消息字符串作为参数
    public String greet(String msg) {
        return name + ": " + msg;
    }
}

// 运用 SpEL 来访问对象的属性与方法
User user = new User();
// 实例化 SpEL 表达式解析器
ExpressionParser parser = new SpelExpressionParser();

// 访问 User 对象的属性
// 解析表达式以获取用户姓名
String name = parser.parseExpression("name").getValue(user, String.class); // "John"

// 调用 User 对象的方法
// 解析表达式以调用 greet 方法并获取问候语
String greeting = parser.parseExpression("greet('Hello')").getValue(user, String.class); // "John: Hello"

// 利用内置函数
// 解析表达式以调用 name 属性的 length 方法获取姓名长度
int length = parser.parseExpression("name.length()").getValue(user, Integer.class); // 4

3. 集合与数组操作

SpEL 提供便捷的语法操作集合和数组。


import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class CollectionExample {
    public static void main(String[] args) {
        // 初始化一个包含整数的列表
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        // 初始化一个包含姓名和年龄映射的 Map
        Map<String, Integer> ages = Map.of("John", 30, "Jane", 25);

        // 实例化 SpEL 表达式解析器
        ExpressionParser parser = new SpelExpressionParser();

        // 访问列表中的元素
        // 解析表达式以获取列表中索引为 2 的元素
        int thirdNumber = parser.parseExpression("[2]").getValue(numbers, Integer.class); // 3

        // 对集合进行过滤操作
        // 解析表达式以筛选出列表中的偶数元素
        List<Integer> evenNumbers = parser.parseExpression("?[#this%2==0]").getValue(numbers, List.class); // [2, 4]

        // 对集合进行映射操作
        // 解析表达式以将列表中的每个元素乘以 2
        List<Integer> doubled = parser.parseExpression("![#this*2]").getValue(numbers, List.class); // [2, 4, 6, 8, 10]

        // 访问 Map 中的值
        // 解析表达式以获取 Map 中键为 "John" 对应的值
        int johnAge = parser.parseExpression("['John']").getValue(ages, Integer.class); // 30
    }
}

4. 条件表达式与三元运算符

使用?:进行条件判断。


// 创建一个 User 类的实例
User user = new User();

// 实例化一个 SpEL 表达式解析器
ExpressionParser parser = new SpelExpressionParser();

// 运用三元运算符进行条件判断
// 解析表达式,根据用户年龄判断其为成人还是未成年人
String status = parser.parseExpression("age > 18 ? 'Adult' : 'Minor'").getValue(user, String.class); 
// 若年龄大于 18 岁,结果为 "Adult"

// 利用 Elvis 运算符简化空值检查
// 解析表达式,若用户姓名不为空则返回姓名,否则返回 'Unknown'
String displayName = parser.parseExpression("name?:'Unknown'").getValue(user, String.class); 
// 若姓名存在,结果为用户实际姓名,此处为 "John"

5. 在 Spring 注解中使用 SpEL

SpEL 常用于依赖注入和条件配置。


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**
 * 应用配置类,用于定义 Spring 应用的配置信息
 */
@Configuration
// 指定属性文件的位置,从类路径下加载 application.properties 文件
@PropertySource("classpath:application.properties")
public class AppConfig {

    /**
     * 从属性文件中注入应用名称
     * 使用 @Value 注解,通过 ${app.name} 从属性文件中获取应用名称
     */
    @Value("${app.name}")
    private String appName;

    /**
     * 使用 SpEL 表达式计算 Java 版本信息
     * 通过 #{systemProperties['java.version']} 获取系统属性中的 Java 版本
     */
    @Value("#{systemProperties['java.version']}")
    private String javaVersion;

    /**
     * 条件注入 MyService 实例
     * 根据属性文件中的 app.production 值决定注入生产环境服务还是开发环境服务
     * @param isProduction 是否为生产环境,通过 SpEL 表达式将属性文件中的值转换为布尔类型
     * @return 根据条件返回 ProductionService 或 DevService 实例
     */
    @Bean
    public MyService myService(@Value("#{new Boolean('${app.production}')}") boolean isProduction) {
        return isProduction ? new ProductionService() : new DevService();
    }
}

6. 自定义函数与变量

通过EvaluationContext注册自定义函数和变量。


import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

/**
 * 自定义函数示例类,展示如何在 SpEL 中注册和使用自定义函数以及变量
 */
public class CustomFunctionExample {
    public static void main(String[] args) {
        // 初始化标准评估上下文,用于注册自定义函数和变量
        StandardEvaluationContext context = new StandardEvaluationContext();

        try {
            // 注册静态方法到评估上下文
            // 此处将 StringUtils 类的 reverse 方法注册为名为 "reverse" 的自定义函数
            context.registerFunction("reverse", StringUtils.class.getMethod("reverse", String.class));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        // 实例化 SpEL 表达式解析器
        ExpressionParser parser = new SpelExpressionParser();

        // 运用注册的自定义函数进行字符串反转操作
        // 解析表达式 "#reverse('Hello')",调用注册的 reverse 函数反转字符串
        String reversed = parser.parseExpression("#reverse('Hello')").getValue(context, String.class); 
        // 结果为 "olleH"

        // 向评估上下文注册变量
        // 注册名为 "factor" 的变量,其值为 2
        context.setVariable("factor", 2);

        // 利用注册的变量进行表达式计算
        // 解析表达式 "3 * #factor",使用注册的变量进行乘法运算
        int result = parser.parseExpression("3 * #factor").getValue(context, Integer.class); 
        // 结果为 6
    }
}

/**
 * 工具类,包含用于字符串反转的静态方法
 */
class StringUtils {
    /**
     * 反转输入字符串
     * @param input 待反转的字符串
     * @return 反转后的字符串
     */
    public static String reverse(String input) {
        return new StringBuilder(input).reverse().toString();
    }
}

7. 正则表达式匹配

使用matches操作符进行正则匹配。


// 实例化一个 SpEL 表达式解析器,用于解析和计算 SpEL 表达式
ExpressionParser parser = new SpelExpressionParser();

// 定义一个 SpEL 表达式,用于验证电子邮件地址的格式
// 表达式中使用了正则表达式来匹配有效的电子邮件地址格式
// 正则表达式 [a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,} 用于匹配符合标准的电子邮件地址
// 这里以 'john@example.com' 作为待验证的电子邮件地址
boolean isValidEmail = parser.parseExpression(
    "'john@example.com' matches '[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}'")
    .getValue(Boolean.class); 

// 输出验证结果,如果 'john@example.com' 符合正则表达式定义的格式,则返回 true,否则返回 false
// 在这个例子中,'john@example.com' 是一个有效的电子邮件地址,所以 isValidEmail 的值为 true
System.out.println("电子邮件地址是否有效: " + isValidEmail); 


8. 安全导航操作符

使用?.避免空指针异常。


// 声明一个 User 类型的变量并初始化为 null,代表当前没有有效的用户对象
User user = null;

// 创建一个 SpEL(Spring Expression Language)表达式解析器实例,用于解析和计算 SpEL 表达式
ExpressionParser parser = new SpelExpressionParser();

/*
 * 使用 SpEL 表达式的安全导航操作符(?.)来尝试获取 user 对象的 name 属性值
 * 安全导航操作符可以避免在 user 为 null 时抛出空指针异常
 * 当 user 为 null 时,表达式会直接返回 null,而不是抛出异常
 * 解析表达式 "?.name" 并尝试从 user 对象中获取 name 属性值,结果存储在 name 变量中
 */
String name = parser.parseExpression("?.name").getValue(user, String.class);

// 输出获取到的 name 值,在 user 为 null 的情况下,name 会是 null
System.out.println("获取到的用户姓名: " + name); 

总结

SpEL 的核心优势在于:

  • 动态求值:运行时解析表达式,无需硬编码。
  • 语法灵活:支持属性访问、方法调用、集合操作、条件表达式等。
  • 集成 Spring:无缝与@Value、XML 配置、AOP 等结合。

掌握 SpEL 能让你的 Spring 代码更简洁、更具表现力!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表