@@ -8,6 +8,8 @@ The Spring Expression Language supports the following kinds of operators:
8
8
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-string[String Operators]
9
9
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-mathematical[Mathematical Operators]
10
10
* xref:core/expressions/language-ref/operators.adoc#expressions-assignment[The Assignment Operator]
11
+ * xref:core/expressions/language-ref/operators.adoc#expressions-operators-overloaded[Overloaded Operators]
12
+
11
13
12
14
13
15
[[expressions-operators-relational]]
@@ -523,3 +525,72 @@ Kotlin::
523
525
======
524
526
525
527
528
+ [[expressions-operators-overloaded]]
529
+ == Overloaded Operators
530
+
531
+ By default, the mathematical operations defined in SpEL's `Operation` enum (`ADD`,
532
+ `SUBTRACT`, `DIVIDE`, `MULTIPLY`, `MODULUS`, and `POWER`) support simple types like
533
+ numbers. By providing an implementation of `OperatorOverloader`, the expression language
534
+ can support these operations on other types.
535
+
536
+ For example, if we want to overload the `ADD` operator to allow two lists to be
537
+ concatenated using the `+` sign, we can implement a custom `OperatorOverloader` as
538
+ follows.
539
+
540
+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
541
+ ----
542
+ pubic class ListConcatenation implements OperatorOverloader {
543
+
544
+ @Override
545
+ public boolean overridesOperation(Operation operation, Object left, Object right) {
546
+ return (operation == Operation.ADD &&
547
+ left instanceof List && right instanceof List);
548
+ }
549
+
550
+ @Override
551
+ @SuppressWarnings("unchecked")
552
+ public Object operate(Operation operation, Object left, Object right) {
553
+ if (operation == Operation.ADD &&
554
+ left instanceof List list1 && right instanceof List list2) {
555
+
556
+ List result = new ArrayList(list1);
557
+ result.addAll(list2);
558
+ return result;
559
+ }
560
+ throw new UnsupportedOperationException(
561
+ "No overload for operation %s and operands [%s] and [%s]"
562
+ .formatted(operation.name(), left, right));
563
+ }
564
+ }
565
+ ----
566
+
567
+ If we register `ListConcatenation` as the `OperatorOverloader` in a
568
+ `StandardEvaluationContext`, we can then evaluate expressions like `{1, 2, 3} + {4, 5}`
569
+ as demonstrated in the following example.
570
+
571
+ [tabs]
572
+ ======
573
+ Java::
574
+ +
575
+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
576
+ ----
577
+ StandardEvaluationContext context = new StandardEvaluationContext();
578
+ context.setOperatorOverloader(new ListConcatenation());
579
+
580
+ // evaluates to a new list: [1, 2, 3, 4, 5]
581
+ parser.parseExpression("{1, 2, 3} + {4, 5}").getValue(context, List.class);
582
+ ----
583
+
584
+ Kotlin::
585
+ +
586
+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
587
+ ----
588
+ StandardEvaluationContext context = StandardEvaluationContext()
589
+ context.setOperatorOverloader(ListConcatenation())
590
+
591
+ // evaluates to a new list: [1, 2, 3, 4, 5]
592
+ parser.parseExpression("{1, 2, 3} + {4, 5}").getValue(context, List::class.java)
593
+ ----
594
+ ======
595
+
596
+
0 commit comments