spring-spel/spring-spel-operatorOverloader/README.md
✒️ 作者 - Lex 📝 博客 - 掘金 📚 源码地址 - github
Spring Expression Language (SpEL)
自定义运算符的概念
OperatorOverloader 接口是 Spring 框架中用于自定义运算符行为的扩展点,允许我们通过实现该接口来定义新的运算符操作,以扩展 Spring 表达式语言(SpEL)的功能,从而实现更灵活和定制化的表达式计算。
自定义运算符行为
支持非标准类型的运算
扩展 SpEL 的功能
提供更灵活的表达式计算
OperatorOverloader 接口定义了用于自定义运算符行为的方法,包括检查是否支持指定的操作以及执行指定操作的方法,从而允许用户扩展 Spring 表达式语言(SpEL)的功能以支持其他类型的操作数。
/**
* 默认情况下,{@link Operation} 支持简单类型(如数字)的数学运算符。
* 通过提供 OperatorOverloader 的实现,表达式语言的用户可以支持对其他类型的操作进行这些运算。
*
* @author Andy Clement
* @since 3.0
*/
public interface OperatorOverloader {
/**
* 如果运算符重载器支持指定操作以及应该调用它来处理该操作,则返回 true。
* @param operation 要执行的操作
* @param leftOperand 左操作数
* @param rightOperand 右操作数
* @return 如果 OperatorOverloader 支持两个操作数之间的指定操作,则返回 true
* @throws EvaluationException 如果执行操作时出现问题
*/
boolean overridesOperation(Operation operation, @Nullable Object leftOperand, @Nullable Object rightOperand)
throws EvaluationException;
/**
* 在两个操作数上执行指定的操作,并返回结果。
* 请参阅 {@link Operation} 以获取支持的操作。
* @param operation 要执行的操作
* @param leftOperand 左操作数
* @param rightOperand 右操作数
* @return 在两个操作数上执行操作的结果
* @throws EvaluationException 如果执行操作时出现问题
*/
Object operate(Operation operation, @Nullable Object leftOperand, @Nullable Object rightOperand)
throws EvaluationException;
}
StandardOperatorOverloader 实现类是 OperatorOverloader 接口的标准实现,其中的方法都是默认实现。在 overridesOperation 方法中,返回 false 表示默认情况下不覆盖任何操作;在 operate 方法中,抛出 EvaluationException 异常表示默认情况下不支持任何操作,提示用户需要自定义运算符行为。
/**
* {@link OperatorOverloader} 的标准实现。
*
* @author Juergen Hoeller
* @since 3.0
*/
public class StandardOperatorOverloader implements OperatorOverloader {
@Override
public boolean overridesOperation(Operation operation, @Nullable Object leftOperand, @Nullable Object rightOperand)
throws EvaluationException {
// 默认情况下不覆盖任何操作
return false;
}
@Override
public Object operate(Operation operation, @Nullable Object leftOperand, @Nullable Object rightOperand)
throws EvaluationException {
// 默认情况下不支持任何操作,抛出异常
throw new EvaluationException("No operation overloaded by default");
}
}
StandardOperatorOverloader 是 OperatorOverloader 接口的标准实现类,旨在提供默认的行为。使用Spring表达式语言(SpEL)中使用自定义的运算符。通过创建 ExpressionParser 对象和 StandardEvaluationContext 上下文,并将自定义的 OperatorOverloader 实例注册到上下文中,我们可以定义并解析包含自定义运算符的SpEL表达式。在这个例子中,我们定义了一个包含自定义加法运算符的SpEL表达式 #myBean1 + #myBean2,然后通过解析并评估该表达式,得到了两个 MyBean 对象的相加结果,并将其打印输出。
public class OperatorOverloaderDemo {
public static void main(String[] args) {
// 创建表达式解析器
ExpressionParser parser = new SpelExpressionParser();
// 创建表达式上下文
StandardEvaluationContext context = new StandardEvaluationContext();
// 创建自定义的OperatorOverloader实例并注册到表达式上下文中
context.setOperatorOverloader(new CustomOperatorOverloader());
context.setVariable("myBean1", new MyBean(18));
context.setVariable("myBean2", new MyBean(20));
// 定义一个SpEL表达式,使用自定义的运算符
Expression expression = parser.parseExpression("#myBean1 + #myBean2");
// 解析并评估表达式
MyBean myBean = expression.getValue(context, MyBean.class);
System.out.println("myBean1+myBean2 = " + myBean);
}
}
CustomOperatorOverloader 类实现了 OperatorOverloader 接口,用于自定义运算符行为。在这个实现中,overridesOperation 方法用于判断是否覆盖了指定的操作,这里检查左右操作数是否都是 MyBean 类型;而 operate 方法用于执行指定的操作,这里是将两个 MyBean 对象的年龄相加,并创建一个新的 MyBean 对象返回。
public class CustomOperatorOverloader implements OperatorOverloader {
@Override
public boolean overridesOperation(Operation operation, Object leftOperand, Object rightOperand) throws EvaluationException {
return leftOperand instanceof MyBean && rightOperand instanceof MyBean;
}
@Override
public Object operate(Operation operation, Object leftOperand, Object rightOperand) throws EvaluationException {
return new MyBean(((MyBean) leftOperand).getAge() + ((MyBean) rightOperand).getAge());
}
}
简单的 Java Bean,包含了一个 age 属性以及对应的 getter 和 setter 方法。它还重写了 toString 方法,以便在输出对象时打印出 age 属性的值。
public class MyBean {
private int age;
public MyBean(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "MyBean{" +
"age=" + age +
'}';
}
}
运行结果,表达式 #myBean1 + #myBean2 中,两个 MyBean 对象的年龄分别是 18 和 20,它们相加的结果为 38。因此输出结果为 MyBean{age=38}。
myBean1+myBean2 = MyBean{age=38}
Operation
Operation 枚举定义了 SpEL 中支持的操作类型,例如加法、减法、乘法等。OperatorOverloader 接口中的方法 overridesOperation 和 operate 使用了 Operation 枚举来表示操作类型,从而确定要执行的操作。EvaluationException
EvaluationException 异常用于表示在表达式评估过程中发生的异常。在 OperatorOverloader 接口的方法中可能会抛出 EvaluationException 异常,用于处理运算符重载过程中可能出现的异常情况。StandardEvaluationContext
StandardEvaluationContext 类是 SpEL 中用于表达式求值的上下文对象。在使用 OperatorOverloader 接口时,可以通过 StandardEvaluationContext 对象设置自定义的 OperatorOverloader 实例,以扩展 SpEL 的功能。运算符重载的正确性
运算符冲突
运算符的一致性
文档和说明