Loading...
Spring Framework Reference Documentation 7.0.2의 Operators의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
The Spring Expression Language은 다음과 같은 종류의 연산자를 지원합니다:
관계 연산자(equal, not equal, less than, less than or equal, greater than,
and greater than or equal)는 표준 연산자 표기법을 사용하여 지원됩니다.
이러한 연산자는 Number 타입뿐만 아니라 Comparable을 구현하는 타입에서도 동작합니다.
다음 예시는 관계 연산자의 몇 가지 예를 보여줍니다:
1// evaluates to true 2boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class); 3 4// evaluates to false 5boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class); 6 7// evaluates to true 8boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class); 9 10// uses CustomValue:::compareTo 11boolean trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean.class);
1// evaluates to true 2val trueValue = parser.parseExpression("2 == 2").getValue(Boolean::class.java) 3 4// evaluates to false 5val falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean::class.java) 6 7// evaluates to true 8val trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean::class.java) 9 10// uses CustomValue:::compareTo 11val trueValue = parser.parseExpression("new CustomValue(1) < new CustomValue(2)").getValue(Boolean::class.java)
null에 대한 greater-than 및 less-than 비교는 간단한 규칙을 따릅니다:null은<br>아무것도 아닌 것으로 취급됩니다(즉, 0으로 취급되지 않습니다). 그 결과, 다른 어떤<br>값도 항상null보다 크며 (X > null은 항상true) 다른 어떤 값도 결코 아무것보다<br>작지 않습니다 (X < null은 항상false).<br>대신 숫자 비교를 선호한다면, 숫자 기반의null비교 대신 0에 대한 비교를<br>사용하십시오(예:X > 0또는X < 0).
각 기호 연산자는 순수하게 텍스트 기반의 동등한 표현으로도 지정할 수 있습니다. 이는 표현식이 포함된 문서 타입(예: XML 문서)에서 사용되는 기호가 특별한 의미를 가지는 경우 발생하는 문제를 방지합니다. 텍스트 기반 동등 표현은 다음과 같습니다:
lt (<)gt (>)le (<=)ge (>=)eq (==)ne (!=)모든 텍스트 기반 연산자는 대소문자를 구분하지 않습니다.
표준 관계 연산자에 더해, SpEL은 between,
instanceof, 그리고 정규식 기반의 matches 연산자를 지원합니다.
다음 예시는 이 세 가지 모두의 예를 보여줍니다:
1boolean result; 2 3// evaluates to true 4result = parser.parseExpression( 5 "1 between {1, 5}").getValue(Boolean.class); 6 7// evaluates to false 8result = parser.parseExpression( 9 "1 between {10, 15}").getValue(Boolean.class); 10 11// evaluates to true 12result = parser.parseExpression( 13 "'elephant' between {'aardvark', 'zebra'}").getValue(Boolean.class); 14 15// evaluates to false 16result = parser.parseExpression( 17 "'elephant' between {'aardvark', 'cobra'}").getValue(Boolean.class); 18 19// evaluates to true 20result = parser.parseExpression( 21 "123 instanceof T(Integer)").getValue(Boolean.class); 22 23// evaluates to false 24result = parser.parseExpression( 25 "'xyz' instanceof T(Integer)").getValue(Boolean.class); 26 27// evaluates to true 28result = parser.parseExpression( 29 "'5.00' matches '^-?\d+(\.\d{2})?$'").getValue(Boolean.class); 30 31// evaluates to false 32result = parser.parseExpression( 33 "'5.0067' matches '^-?\d+(\.\d{2})?$'").getValue(Boolean.class);
1// evaluates to true 2var result = parser.parseExpression( 3 "1 between {1, 5}").getValue(Boolean::class.java) 4 5// evaluates to false 6result = parser.parseExpression( 7 "1 between {10, 15}").getValue(Boolean::class.java) 8 9// evaluates to true 10result = parser.parseExpression( 11 "'elephant' between {'aardvark', 'zebra'}").getValue(Boolean::class.java) 12 13// evaluates to false 14result = parser.parseExpression( 15 "'elephant' between {'aardvark', 'cobra'}").getValue(Boolean::class.java) 16 17// evaluates to true 18result = parser.parseExpression( 19 "123 instanceof T(Integer)").getValue(Boolean::class.java) 20 21// evaluates to false 22result = parser.parseExpression( 23 "'xyz' instanceof T(Integer)").getValue(Boolean::class.java) 24 25// evaluates to true 26result = parser.parseExpression( 27 "'5.00' matches '^-?\d+(\.\d{2})?$'").getValue(Boolean::class.java) 28 29// evaluates to false 30result = parser.parseExpression( 31 "'5.0067' matches '^-?\d+(\.\d{2})?$'").getValue(Boolean::class.java)
between연산자의 구문은<input> between {<range_begin>, <range_end>}이며,<br>이는 사실상<input> >= <range_begin> && <input> <= <range_end>}에 대한<br>단축 표기입니다.<br>따라서,1 between {1, 5}는true로 평가되고,1 between {5, 1}은<br>false로 평가됩니다.
기본 타입에 주의해야 합니다. 기본 타입은 즉시 해당 래퍼 타입으로<br>박싱되기 때문입니다. 예를 들어,
1 instanceof T(int)는false로 평가되는 반면,<br>1 instanceof T(Integer)는true로 평가됩니다.
SpEL은 다음과 같은 논리(boolean) 연산자를 지원합니다:
and (&&)or (||)not (!)모든 텍스트 기반 연산자는 대소문자를 구분하지 않습니다.
다음 예시는 논리 연산자의 사용 방법을 보여줍니다:
1// -- AND -- 2 3// evaluates to false 4boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class); 5 6// evaluates to true 7String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"; 8boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); 9 10// -- OR -- 11 12// evaluates to true 13boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class); 14 15// evaluates to true 16expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')"; 17trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); 18 19// -- NOT -- 20 21// evaluates to false 22falseValue = parser.parseExpression("!true").getValue(Boolean.class); 23 24// -- AND and NOT -- 25 26expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"; 27falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
1// -- AND -- 2 3// evaluates to false 4val falseValue = parser.parseExpression("true and false").getValue(Boolean::class.java) 5 6// evaluates to true 7var expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')" 8val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java) 9 10// -- OR -- 11 12// evaluates to true 13val trueValue2 = parser.parseExpression("true or false").getValue(Boolean::class.java) 14 15// evaluates to true 16expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')" 17val trueValue3 = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java) 18 19// -- NOT -- 20 21// evaluates to false 22val falseValue2 = parser.parseExpression("!true").getValue(Boolean::class.java) 23 24// -- AND and NOT -- 25 26expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')" 27val falseValue3 = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
다음 연산자를 String에 사용할 수 있습니다.
+)-)
*)다음 예시는 String 연산자의 사용 예를 보여줍니다:
1// -- Concatenation -- 2 3// evaluates to "hello world" 4String helloWorld = parser.parseExpression("'hello' + ' ' + 'world'") 5 .getValue(String.class); 6 7// -- Character Subtraction -- 8 9// evaluates to 'a' 10char ch = parser.parseExpression("'d' - 3") 11 .getValue(char.class); 12 13// -- Repeat -- 14 15// evaluates to "abcabc" 16String repeated = parser.parseExpression("'abc' * 2") 17 .getValue(String.class);
1// -- Concatenation -- 2 3// evaluates to "hello world" 4val helloWorld = parser.parseExpression("'hello' + ' ' + 'world'") 5 .getValue(String::class.java) 6 7// -- Character Subtraction -- 8 9// evaluates to 'a' 10val ch = parser.parseExpression("'d' - 3") 11 .getValue(Character::class.java) 12 13// -- Repeat -- 14 15// evaluates to "abcabc" 16val repeated = parser.parseExpression("'abc' * 2") 17 .getValue(String::class.java)
다음 연산자를 숫자에 사용할 수 있으며, 표준 연산자 우선순위가 적용됩니다.
+)-)++)--)*)/)%)^)나눗셈 및 나머지 연산자는 순수하게 텍스트 기반의 동등 표현으로도 지정할 수 있습니다. 이는 표현식이 포함된 문서 타입(예: XML 문서)에서 사용되는 기호가 특별한 의미를 가지는 경우 발생하는 문제를 방지합니다. 텍스트 기반 동등 표현은 다음과 같습니다:
div (/)mod (%)모든 텍스트 기반 연산자는 대소문자를 구분하지 않습니다.
증가 및 감소 연산자는 쓰기가 가능한 변수 또는 프로퍼티에 대해<br>접두(prefix) 표기법(
++A,--A) 또는 접미(postfix) 표기법(A++,A--) 모두 사용할 수 있습니다.
다음 예시는 수학 연산자의 사용 예를 보여줍니다:
1Inventor inventor = new Inventor(); 2EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); 3 4// -- Addition -- 5 6int two = parser.parseExpression("1 + 1").getValue(int.class); // 2 7 8// -- Subtraction -- 9 10int four = parser.parseExpression("1 - -3").getValue(int.class); // 4 11 12double d = parser.parseExpression("1000.00 - 1e4").getValue(double.class); // -9000 13 14// -- Increment -- 15 16// The counter property in Inventor has an initial value of 0. 17 18// evaluates to 2; counter is now 1 19two = parser.parseExpression("counter++ + 2").getValue(context, inventor, int.class); 20 21// evaluates to 5; counter is now 2 22int five = parser.parseExpression("3 + ++counter").getValue(context, inventor, int.class); 23 24// -- Decrement -- 25 26// The counter property in Inventor has a value of 2. 27 28// evaluates to 6; counter is now 1 29int six = parser.parseExpression("counter-- + 4").getValue(context, inventor, int.class); 30 31// evaluates to 5; counter is now 0 32five = parser.parseExpression("5 + --counter").getValue(context, inventor, int.class); 33 34// -- Multiplication -- 35 36six = parser.parseExpression("-2 * -3").getValue(int.class); // 6 37 38double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(double.class); // 24.0 39 40// -- Division -- 41 42int minusTwo = parser.parseExpression("6 / -3").getValue(int.class); // -2 43 44double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(double.class); // 1.0 45 46// -- Modulus -- 47 48int three = parser.parseExpression("7 % 4").getValue(int.class); // 3 49 50int oneInt = parser.parseExpression("8 / 5 % 2").getValue(int.class); // 1 51 52// -- Exponential power -- 53 54int maxInt = parser.parseExpression("(2^31) - 1").getValue(int.class); // Integer.MAX_VALUE 55 56int minInt = parser.parseExpression("-2^31").getValue(int.class); // Integer.MIN_VALUE 57 58// -- Operator precedence -- 59 60int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(int.class); // -21
1val inventor = Inventor() 2val context = SimpleEvaluationContext.forReadWriteDataBinding().build() 3 4// -- Addition -- 5 6var two = parser.parseExpression("1 + 1").getValue(Int::class.java) // 2 7 8// -- Subtraction -- 9 10val four = parser.parseExpression("1 - -3").getValue(Int::class.java) // 4 11 12val d = parser.parseExpression("1000.00 - 1e4").getValue(Double::class.java) // -9000 13 14// -- Increment -- 15 16// The counter property in Inventor has an initial value of 0. 17 18// evaluates to 2; counter is now 1 19two = parser.parseExpression("counter++ + 2").getValue(context, inventor, Int::class.java) 20 21// evaluates to 5; counter is now 2 22var five = parser.parseExpression("3 + ++counter").getValue(context, inventor, Int::class.java) 23 24// -- Decrement -- 25 26// The counter property in Inventor has a value of 2. 27 28// evaluates to 6; counter is now 1 29var six = parser.parseExpression("counter-- + 4").getValue(context, inventor, Int::class.java) 30 31// evaluates to 5; counter is now 0 32five = parser.parseExpression("5 + --counter").getValue(context, inventor, Int::class.java) 33 34// -- Multiplication -- 35 36six = parser.parseExpression("-2 * -3").getValue(Int::class.java) // 6 37 38val twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double::class.java) // 24.0 39 40// -- Division -- 41 42val minusTwo = parser.parseExpression("6 / -3").getValue(Int::class.java) // -2 43 44val one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double::class.java) // 1.0 45 46// -- Modulus -- 47 48val three = parser.parseExpression("7 % 4").getValue(Int::class.java) // 3 49 50val oneInt = parser.parseExpression("8 / 5 % 2").getValue(Int::class.java) // 1 51 52// -- Exponential power -- 53 54val maxInt = parser.parseExpression("(2^31) - 1").getValue(Int::class.java) // Integer.MAX_VALUE 55 56val minInt = parser.parseExpression("-2^31").getValue(Int::class.java) // Integer.MIN_VALUE 57 58// -- Operator precedence -- 59 60val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java) // -21
프로퍼티를 설정하려면 할당 연산자(=)를 사용하십시오.
이는 일반적으로 setValue 호출 내에서 수행되지만, getValue 호출 내부에서도 수행될 수 있습니다.
다음 예시는 할당 연산자를 사용하는 두 가지 방법을 보여줍니다:
1Inventor inventor = new Inventor(); 2EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); 3 4parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic"); 5 6// alternatively 7String aleks = parser.parseExpression( 8 "name = 'Aleksandar Seovic'").getValue(context, inventor, String.class);
1val inventor = Inventor() 2val context = SimpleEvaluationContext.forReadWriteDataBinding().build() 3 4parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic") 5 6// alternatively 7val aleks = parser.parseExpression( 8 "name = 'Aleksandar Seovic'").getValue(context, inventor, String::class.java)
기본적으로, SpEL의 Operation enum (ADD,
SUBTRACT, DIVIDE, MULTIPLY, MODULUS, 그리고 POWER)에 정의된 수학 연산은
숫자와 같은 단순 타입을 지원합니다.
OperatorOverloader 구현을 제공하면,
표현식 언어는 이러한 연산을 다른 타입에서도 지원할 수 있습니다.
예를 들어, 두 리스트를 + 기호를 사용하여
연결하도록 ADD 연산자를 오버로드하려는 경우, 다음과 같이 커스텀
OperatorOverloader를 구현할 수 있습니다.
1pubic class ListConcatenation implements OperatorOverloader { 2 3 @Override 4 public boolean overridesOperation(Operation operation, Object left, Object right) { 5 return (operation == Operation.ADD && 6 left instanceof List && right instanceof List); 7 } 8 9 @Override 10 public Object operate(Operation operation, Object left, Object right) { 11 if (operation == Operation.ADD && 12 left instanceof List list1 && right instanceof List list2) { 13 14 List result = new ArrayList(list1); 15 result.addAll(list2); 16 return result; 17 } 18 throw new UnsupportedOperationException( 19 "No overload for operation %s and operands [%s] and [%s]" 20 .formatted(operation, left, right)); 21 } 22}
StandardEvaluationContext에 OperatorOverloader로 ListConcatenation을
등록하면, 다음 예시에서와 같이 {1, 2, 3} + {4, 5}와 같은 표현식을 평가할 수 있습니다.
1StandardEvaluationContext context = new StandardEvaluationContext(); 2context.setOperatorOverloader(new ListConcatenation()); 3 4// evaluates to a new list: [1, 2, 3, 4, 5] 5parser.parseExpression("{1, 2, 3} + {2 + 2, 5}").getValue(context, List.class);
1val context = StandardEvaluationContext() 2context.setOperatorOverloader(ListConcatenation()) 3 4// evaluates to a new list: [1, 2, 3, 4, 5] 5parser.parseExpression("{1, 2, 3} + {2 + 2, 5}").getValue(context, List::class.java)
OperatorOverloader는 연산자에 대한 기본 의미론을 변경하지 않습니다.<br>예를 들어, 위 예시에서2 + 2는 여전히4로 평가됩니다.
오버로드된 연산자를 사용하는 표현식은 컴파일될 수 없습니다. 자세한 내용은<br>Compiler Limitations을<br>참조하십시오.
Methods
Types