SpEL表达式

现代的软件开发,瞄准的是一个低耦合低代码的理解,如何使用逻辑分离,数据单独管理的操作,才是一个现代程序开发人员应该掌握的东西,不应该进行逻辑的冗余理解!

image-20231125202244341

image-20231125203053921

总体来讲,这里利用数组进行的操作,我觉得不是非常妥当,效率下降了许多!还是觉得用栈非常的优质,无论是实现什么操作,这都比单纯的数组要来的痛快,并且高效

语法解析:

https://zhuanlan.zhihu.com/p/453333109

这里源码进行了封装,我就无法就去进行理解了,到是得到了一个非常牛逼的小知识,这也是idea的魔法,解析用户输入的操作,然后将相关的东西进行解析,返回给用户,然后利用用户选择的操作再进行操作

生成抽象表达式对象

这个生成的表达式对象利用expression进行封装,封装了之后里面存在一些调用对象的相关参数的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.expression;

import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;

/**
* An expression capable of evaluating itself against context objects.
* Encapsulates the details of a previously parsed expression string.
* Provides a common abstraction for expression evaluation.
*
* @author Keith Donald
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
public interface Expression {

/**
* Return the original string used to create this expression (unmodified).
* @return the original expression string
*/
String getExpressionString();

/**
* Evaluate this expression in the default standard context.
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
Object getValue() throws EvaluationException;

/**
* Evaluate the expression in the default context. If the result
* of the evaluation does not match (and cannot be converted to)
* the expected result type then an exception will be returned.
* @param desiredResultType the class the caller would like the result to be
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
<T> T getValue(@Nullable Class<T> desiredResultType) throws EvaluationException;

/**
* Evaluate this expression against the specified root object.
* @param rootObject the root object against which to evaluate the expression
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
Object getValue(@Nullable Object rootObject) throws EvaluationException;

/**
* Evaluate the expression in the default context against the specified root
* object. If the result of the evaluation does not match (and cannot be
* converted to) the expected result type then an exception will be returned.
* @param rootObject the root object against which to evaluate the expression
* @param desiredResultType the class the caller would like the result to be
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
<T> T getValue(@Nullable Object rootObject, @Nullable Class<T> desiredResultType) throws EvaluationException;

/**
* Evaluate this expression in the provided context and return the result
* of evaluation.
* @param context the context in which to evaluate the expression
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
Object getValue(EvaluationContext context) throws EvaluationException;

/**
* Evaluate this expression in the provided context and return the result
* of evaluation, but use the supplied root context as an override for any
* default root object specified in the context.
* @param context the context in which to evaluate the expression
* @param rootObject the root object against which to evaluate the expression
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
Object getValue(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException;

/**
* Evaluate the expression in a specified context which can resolve references
* to properties, methods, types, etc. The type of the evaluation result is
* expected to be of a particular class and an exception will be thrown if it
* is not and cannot be converted to that type.
* @param context the context in which to evaluate the expression
* @param desiredResultType the class the caller would like the result to be
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
<T> T getValue(EvaluationContext context, @Nullable Class<T> desiredResultType) throws EvaluationException;

/**
* Evaluate the expression in a specified context which can resolve references
* to properties, methods, types, etc. The type of the evaluation result is
* expected to be of a particular class and an exception will be thrown if it
* is not and cannot be converted to that type. The supplied root object
* overrides any default specified on the supplied context.
* @param context the context in which to evaluate the expression
* @param rootObject the root object against which to evaluate the expression
* @param desiredResultType the class the caller would like the result to be
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
@Nullable
<T> T getValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Class<T> desiredResultType)
throws EvaluationException;

/**
* Return the most general type that can be passed to a {@link #setValue}
* method using the default context.
* @return the most general type of value that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
Class<?> getValueType() throws EvaluationException;

/**
* Return the most general type that can be passed to the
* {@link #setValue(Object, Object)} method using the default context.
* @param rootObject the root object against which to evaluate the expression
* @return the most general type of value that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
Class<?> getValueType(@Nullable Object rootObject) throws EvaluationException;

/**
* Return the most general type that can be passed to the
* {@link #setValue(EvaluationContext, Object)} method for the given context.
* @param context the context in which to evaluate the expression
* @return the most general type of value that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
Class<?> getValueType(EvaluationContext context) throws EvaluationException;

/**
* Return the most general type that can be passed to the
* {@link #setValue(EvaluationContext, Object, Object)} method for the given
* context. The supplied root object overrides any specified in the context.
* @param context the context in which to evaluate the expression
* @param rootObject the root object against which to evaluate the expression
* @return the most general type of value that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
Class<?> getValueType(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException;

/**
* Return the most general type that can be passed to a {@link #setValue}
* method using the default context.
* @return a type descriptor for values that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
TypeDescriptor getValueTypeDescriptor() throws EvaluationException;

/**
* Return the most general type that can be passed to the
* {@link #setValue(Object, Object)} method using the default context.
* @param rootObject the root object against which to evaluate the expression
* @return a type descriptor for values that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
TypeDescriptor getValueTypeDescriptor(@Nullable Object rootObject) throws EvaluationException;

/**
* Return the most general type that can be passed to the
* {@link #setValue(EvaluationContext, Object)} method for the given context.
* @param context the context in which to evaluate the expression
* @return a type descriptor for values that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
TypeDescriptor getValueTypeDescriptor(EvaluationContext context) throws EvaluationException;

/**
* Return the most general type that can be passed to the
* {@link #setValue(EvaluationContext, Object, Object)} method for the given
* context. The supplied root object overrides any specified in the context.
* @param context the context in which to evaluate the expression
* @param rootObject the root object against which to evaluate the expression
* @return a type descriptor for values that can be set on this context
* @throws EvaluationException if there is a problem determining the type
*/
@Nullable
TypeDescriptor getValueTypeDescriptor(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException;

/**
* Determine if an expression can be written to, i.e. setValue() can be called.
* @param rootObject the root object against which to evaluate the expression
* @return {@code true} if the expression is writable; {@code false} otherwise
* @throws EvaluationException if there is a problem determining if it is writable
*/
boolean isWritable(@Nullable Object rootObject) throws EvaluationException;

/**
* Determine if an expression can be written to, i.e. setValue() can be called.
* @param context the context in which the expression should be checked
* @return {@code true} if the expression is writable; {@code false} otherwise
* @throws EvaluationException if there is a problem determining if it is writable
*/
boolean isWritable(EvaluationContext context) throws EvaluationException;

/**
* Determine if an expression can be written to, i.e. setValue() can be called.
* The supplied root object overrides any specified in the context.
* @param context the context in which the expression should be checked
* @param rootObject the root object against which to evaluate the expression
* @return {@code true} if the expression is writable; {@code false} otherwise
* @throws EvaluationException if there is a problem determining if it is writable
*/
boolean isWritable(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException;

/**
* Set this expression in the provided context to the value provided.
* @param rootObject the root object against which to evaluate the expression
* @param value the new value
* @throws EvaluationException if there is a problem during evaluation
*/
void setValue(@Nullable Object rootObject, @Nullable Object value) throws EvaluationException;

/**
* Set this expression in the provided context to the value provided.
* @param context the context in which to set the value of the expression
* @param value the new value
* @throws EvaluationException if there is a problem during evaluation
*/
void setValue(EvaluationContext context, @Nullable Object value) throws EvaluationException;

/**
* Set this expression in the provided context to the value provided.
* The supplied root object overrides any specified in the context.
* @param context the context in which to set the value of the expression
* @param rootObject the root object against which to evaluate the expression
* @param value the new value
* @throws EvaluationException if there is a problem during evaluation
*/
void setValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Object value) throws EvaluationException;

}

一般此处的上下文对象进行的都是标准的对象上下文,当然也存在很多的实现,但是现在遇到了就只是单纯的一个类实现

image-20231125205814903

第一个EL表达式DEMO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
	package com.example.springdemo.entity.SpEL;

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;

public class theSpeL {
public static void main(String[] args) {
//创建语法解析器
ExpressionParser expressionParser=new SpelExpressionParser();
//创建一个el表达式字符串
String theSpeLString="(('Hello')+('queen')).toUpperCase()+(' ')+('my husband is:')+(#jack)";
//语法进行解析操作
Expression express=expressionParser.parseExpression(theSpeLString);
//创建一个标准上下文内容操作器
//注意此处使用标准上下文处理器进行操作
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("jack","king");
//获取处理之后的表达式字符串
System.out.println(express.getValue());

//以上就是总体的EL表达式的参数传递,总体用起来是非常简单的
}
}

EL表达式语法:

image-20231122204501362

字面量表达式

image-20231124170428041

什么叫做字面量?字面量就是计算机中默认的固定值变量,也就是当程序员没有进行字面量设置的时候,也就是空值操作的时候,某些语言可以进行赋值,但是某些语言不会进行赋值操作,需要进行联合理解,也叫默认值,也叫初始值!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.example.springdemo.entity.SpEL;

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

import java.util.Arrays;
import java.util.Optional;

public class theSpeLType {
public static void main(String[] args){
//创建表达式解析器
ExpressionParser expressionParser=new SpelExpressionParser();
//利用解析器去进行解析相关句法操作
String theFirstGod=expressionParser.parseExpression("'Zeus'").getValue(String.class);
System.out.println(Optional.of(expressionParser.parseExpression("'2'").getValue(Integer.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'2.0'").getValue(Float.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'2'").getValue(Double.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'true'").getValue(boolean.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'d'").getValue(Character.class).getClass().getName()));
//那不也是单个字符串之间的理解操作吗
System.out.println(Optional.of(expressionParser.parseExpression("'2'").getValue(byte.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'2'").getValue(char.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'2'").getValue(long.class).getClass().getName()));
System.out.println(Optional.of(expressionParser.parseExpression("'0x333'").getValue(Integer.class).getClass().getName()));
//EL表达式能够将十六进制数转换为10进制数,优点厉害,又是一个非常优质的实现
Integer value = expressionParser.parseExpression("'0x333'").getValue(Integer.class);
System.out.println(value);
}
}

SpEL表达式能够将十六进制数直接转换为十进制数,这是底层进行的封装操作,不深入理解了,总体的逻辑就是那个样子

算数表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.example.springdemo.entity.SpEL;

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

import java.math.BigInteger;

public class operationSpEL {
public static void main(String[] args) {
//加减乘除求余数
ExpressionParser express=new SpelExpressionParser();
//原来中间的特殊符号是储存在这个地方的
String theAddResult="3+2";
String theSubResult="99-88";
String theMutiResult="3000*89832";
String theModResult="99999/3232";
String theModResult2="200%2";
String theMidResult3="2^55";
String theDiffcultResults="3+24234+23423-9883*(2344^22)/33%23";
Expression expression = express.parseExpression(theAddResult);
System.out.println(expression.getValue());
System.out.println(express.parseExpression(theSubResult).getValue(Integer.class));
System.out.println(express.parseExpression(theMutiResult).getValue(Integer.class));
System.out.println(express.parseExpression(theModResult).getValue(Integer.class));
System.out.println(express.parseExpression(theModResult2).getValue(Integer.class));
System.out.println(express.parseExpression(theMidResult3).getValue(BigInteger.class));
System.out.println(express.parseExpression(theDiffcultResults).getValue(BigInteger.class));
}
}

关系表达式

点评:关系表达式可以利用符号进行理解与实现,当然也可以像sql一样进行操作,利用表达式 GT LT BETWEEN …..进行操作

关于使用英文大写操作的传递,此处我翻看了其底层源码

image-20231122213500313

这是支持的几种符号化的语言:除,相等,大于,大于等于,小于,小于等于,取模,不等于,取反

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.springdemo.entity.SpEL;

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

import java.sql.SQLOutput;

public class theRelationShipSpEL {
public static void main(String[] args) {
//第一步创建一个语法解析器
ExpressionParser expression=new SpelExpressionParser();
System.out.println(expression.parseExpression("1>=2").getValue(Boolean.class));
System.out.println(expression.parseExpression("1>=2 && 2<3 && 4>5 && 1!=1").getValue(Boolean.class));
System.out.println(expression.parseExpression("1>=2 || 3>2").getValue(Boolean.class));
System.out.println(expression.parseExpression("1==2").getValue(Boolean.class));
System.out.println(expression.parseExpression("1!=2").getValue(Boolean.class));
System.out.println(expression.parseExpression("3<=5").getValue(Boolean.class));
System.out.println(expression.parseExpression("1 between {1,2}").getValue(Boolean.class));
System.out.println(expression.parseExpression("0 between {2,3}").getValue(Boolean.class));

//关于布尔取反呢?
System.out.println(expression.parseExpression("!true").getValue(Boolean.class));
//是否区分大小写?
System.out.println(expression.parseExpression("1 gt 2").getValue(Boolean.class));
System.out.println(expression.parseExpression("1 GT 2").getValue(Boolean.class));

System.out.println("-----------------------------------------------------------------------");

/*
LOGIC SpEL:我自己所形成的一套理解操作,关于实现SpEL表达式所进行的理解操作,使用相关英文的理解形式来进行求解操作
**/
System.out.println(expression.parseExpression("(99 GT (33-20)) AND true").getValue(Boolean.class));
System.out.println(expression.parseExpression("NOT (2 BETWEEN {2,3})").getValue(Boolean.class));
System.out.println(expression.parseExpression("6>8 AND (1 GT 2) || ((2 LT 3) AND NOT true)").getValue(Boolean.class));

}
}

逻辑表达式

&& || ! AND OR NOT也可以进行逻辑操作

1
2
3
4
5
6
7
/*
LOGIC SpEL:我自己所形成的一套理解操作,关于实现SpEL表达式所进行的理解操作,使用相关英文的理解形式来进行求解操作
**/
System.out.println(expression.parseExpression("(99 GT (33-20)) AND true").getValue(Boolean.class));
System.out.println(expression.parseExpression("NOT (2 BETWEEN {2,3})").getValue(Boolean.class));
System.out.println(expression.parseExpression("6>8 AND (1 GT 2) || ((2 LT 3) AND NOT true)").getValue(Boolean.class));

三目运算符

EL表达式支持三目运算符

1
System.out.println(expression.parseExpression("(3>2)?'3大于2':'3小于2,错误'").getValue());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.springdemo.entity.SpEL;

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

public class theStringSplit {
public static void main(String[] args) {
//利用括号,具备最高的优先级操作
ExpressionParser express=new SpelExpressionParser();
System.out.println(express.parseExpression("'i am the Zeus'[9]").getValue());

System.out.println(express.parseExpression("3 GT 2 ? true:false").getValue());
System.out.println(express.parseExpression("3 GT 2 ? '正确':('错误')").getValue());
}
}

类表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.springdemo.entity.SpEL;

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

import javax.print.DocFlavor;
import java.util.Objects;

public class TheClassSpEL {
public static void main(String[] args) {
//创建语法解析器
ExpressionParser expressionParser=new SpelExpressionParser();
String theClassSpEL="T(String)";
Expression expression=expressionParser.parseExpression(theClassSpEL);
//关于控制空指针的方法,此方法的源码是不会产生空指针的
//return (a==b) || (a!=null && a.equals(b))
//当a==null的时候,函数返回值是不存在的,这就非常优质的表明了null指针是能够被处理的
System.out.println(Objects.equals(expression.getValue(Class.class), String.class));

//获取类中的静态变量
String theClassSpEL2="T(Integer).MAX_VALUE";
Expression expression2=expressionParser.parseExpression(theClassSpEL2);
System.out.println(expression2.getValue());

//获取类中的静态方法调用
String theClassSpEL3="T(Integer).toHexString('987')";
Expression expression3=expressionParser.parseExpression(theClassSpEL3);
System.out.println(expression3.getValue());

//获取其他包中的类
String theClassSpEL4="T(com.example.springdemo.entity.SpEL.operationSpEL)";
Expression expression4=expressionParser.parseExpression(theClassSpEL4);
System.out.println(expression4.getValue(Class.class));

//什么时候该运用字符串进行操作什么时候不运用字符串进行操作那是非常需要注意的

}
}

如果存在一个空都是不会进行输出的,只有都为非空的情况才会进行输出

类实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.springdemo.entity.SpEL;

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

public class instanceSpEL {
public static void main(String[] args) {
//创建一个EL表达式解析类
ExpressionParser expression=new SpelExpressionParser();
//关键是构造参数理解操作,如何对相关的操作进行非常优质的理解
String theNewInstance="new String('Acis')";
String value = expression.parseExpression(theNewInstance).getValue(String.class);
System.out.println(value);

//构造参数进行非常规理解操作
String theNewInstance2="new Integer('417')";
Integer MyName=expression.parseExpression(theNewInstance2).getValue(Integer.class);
System.out.println(MyName);
System.out.println(MyName.getClass().getTypeName());
}
}

INSTANCEOF表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.springdemo.entity.SpEL;

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

public class InstanceOfSpEL {
public static void main(String[] args) {
ExpressionParser expres=new SpelExpressionParser();
String theInstanceOf="'jack' instanceof T(String)";
Expression expression=expres.parseExpression(theInstanceOf);
System.out.println(expression.getValue());
}
}

检验类是否集成相关类的关键字,这些基本上都是java中老生常谈的问题了,我就不过多赘述了

上下文root变量的设置已经自定义变量的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.example.springdemo.entity.SpEL;

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

public class theVariable {
public static void main(String[] args) {
ExpressionParser expres=new SpelExpressionParser();
//标准上下文对象
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("Zeus","jack");
evaluationContext.setVariable("jack","queen");
evaluationContext.setVariable("some","theInnerTest");
//这种直接进行的操作是非常优质的理解之一,如何进行其中的参数设置那才是必要的
System.out.println(expres.parseExpression("#Zeus").getValue(evaluationContext,expres));
System.out.println(expres.parseExpression("#jack").getValue(evaluationContext,expres));
System.out.println(expres.parseExpression("#some").getValue(evaluationContext,expres));
String value = expres.parseExpression("#this").getValue(evaluationContext, String.class);
System.out.println(value);
//创建一个根对象理解操作
EvaluationContext evaluationContextRooter=new StandardEvaluationContext("i am the rooter");
System.out.println(expres.parseExpression("#root").getValue(evaluationContextRooter,String.class));
System.out.println(expres.parseExpression("#this").getValue(evaluationContextRooter, String.class));
}
}

如果你并没有实现自定义变量的操作,那么你就必须使用相关的root对象操作来进行理解,其内置一个根对象,可以通过#root进行访问,当然了,你也可以通过#this对当前所获取的变量进行操作,this 指当前变量的理解

自定义函数

利用反射进行类的方法获取,然后将获取到的类的方法传入上下文自定义变量之中,然后再调用相关键进行获取方法,传入参数实现自定义函数的操作,利用反射的操作着实有点厉害!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.springdemo.entity.SpEL;

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;

import java.lang.reflect.Method;
import java.util.Arrays;

public class theDiyFunctionSpEL {
public static void main(String[] args) throws NoSuchMethodException {
//利用反射来进行自定义的函数名称设置操作
StandardEvaluationContext evaluationContext=new StandardEvaluationContext();
//反射的知识依然是需要进行回看的,此处的反射知识有一点生疏了
Method method= Integer.class.getDeclaredMethod("parseInt", String.class);
ExpressionParser expression=new SpelExpressionParser();
evaluationContext.setVariable("parseInt1",method);
evaluationContext.registerFunction("parseInt2",method);

//创建相关的理解操作
System.out.println(expression.parseExpression("#parseInt1('333')")
.getValue(evaluationContext,Integer.class)
.getClass().getTypeName());
//实现自定义注解操作
System.out.println(expression.parseExpression("#parseInt2('2424')")
.getValue(evaluationContext, Integer.class)
.getClass()
.getTypeName());
//现在关于直接将类型进行转化又多了一种方式,利用SpEL表达式进行操作
}
}

表达式赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.example.springdemo.entity.SpEL;


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

@Data
public class theObjectValueSpELTest {
//名称
public String name;
//年龄
protected Integer age;
//描述
protected String description;
//性格
protected String thePersonality;
//静态代码块
static {
System.out.println("静态代码块进行加载了");
//创建句法解析器
ExpressionParser parser = new SpelExpressionParser();
//传递对象进去了
theObjectValueSpELTest theObjectValueSpellExpress=new theObjectValueSpELTest();
theObjectValueSpellExpress.setName("Apollo");
StandardEvaluationContext evaluationContext=new StandardEvaluationContext(theObjectValueSpellExpress);
System.out.println(parser.parseExpression("#root.name").getValue(evaluationContext,String.class));
}
static {
//创建词法解析器
ExpressionParser expressionParser=new SpelExpressionParser();
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("theObject",new theObjectValueSpELTest());
expressionParser.parseExpression("#theObject.name").setValue(evaluationContext,"Zeus");
System.out.println(expressionParser.parseExpression("#theObject.name").getValue(evaluationContext,String.class));
}

public static void main(String[] args) {
theObjectValueSpELTest theObjectValueSpElement=new theObjectValueSpELTest();
//并非永久性的操作
System.out.println(theObjectValueSpElement.getName());

ExpressionParser parser = new SpelExpressionParser();
//传递对象进去了
theObjectValueSpELTest theObjectValueSpellExpress=new theObjectValueSpELTest();
theObjectValueSpellExpress.setName("Apollo");
StandardEvaluationContext evaluationContext=new StandardEvaluationContext(theObjectValueSpellExpress);
System.out.println(parser.parseExpression("#root.name").getValue(evaluationContext,String.class));
}
}

当然了,可以利用相关的操作实现永久化的储存,但是需要你在不同的时期干不同的事情,如何专注于对象的操作那才是必要的

安全表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.springdemo.entity.SpEL;

import com.example.springdemo.entity.SpEL.pojo.theBicycleFactoryInfo;
import com.example.springdemo.entity.SpEL.pojo.theBicycleInfo;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class safeIndexToGet {
public static void main(String[] args) {
theBicycleInfo theBicycleInfo=new theBicycleInfo();
//创建简单的解析器
ExpressionParser expressionParser=new SpelExpressionParser();
//使用相关的上下文解析器操作
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("theBicycleInfo",theBicycleInfo);
//嵌套类进行传递的时候原本的类是无法进行感知的,故调用的时候会出现一定的错误操作,产生空指针理解
// System.out.println(expressionParser.parseExpression("#theBicycleInfo.theBicycleFactoryInfo.factoryName").getValue(evaluationContext, String.class));
//安全访问修饰符可以进行相关的空对象的传递操作,可以进行非空的操作
System.out.println(expressionParser.parseExpression("#theBicycleInfo?.theBicycleFactoryInfo?.factoryName").getValue(evaluationContext, String.class));
// theBicycleFactoryInfo theBicycleFactoryInfo=new theBicycleFactoryInfo();
// theBicycleFactoryInfo.setFactoryLocation("CDC");
// theBicycleFactoryInfo.setFactoryName("XDS");
// theBicycleFactoryInfo.setFactoryPrice(2000);

theBicycleInfo.setName("Zeus");
theBicycleInfo.setAge(32);
theBicycleInfo.setTheBicycleType("XDS");
theBicycleInfo.setDescription("mountainCap");
// theBicycleInfo.setTheBicycleFactoryInfo(theBicycleFactoryInfo);

EvaluationContext evaluationContextDetail=new StandardEvaluationContext();
evaluationContextDetail.setVariable("theInnerBicycleInfo",theBicycleInfo);
//关键进行的传递理解
System.out.println(expressionParser.parseExpression("#theInnerBicycleInfo?.theBicycleFactoryInfo?.factoryName").getValue(evaluationContextDetail, String.class));
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.springdemo.entity.SpEL.pojo;


import lombok.Data;

@Data
public class theBicycleInfo {
public String name;
public Integer age;
public String theBicycleType;
public String Description;
public theBicycleFactoryInfo theBicycleFactoryInfo;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.springdemo.entity.SpEL.pojo;

import lombok.Builder;
import lombok.Data;


@Data
@Builder
public class theBicycleFactoryInfo {
public String factoryName;
public Integer factoryPrice;
public String FactoryLocation;
}

当然了也可以实现root的调用操作,利用root来对相关操作进行调用理解,当然也能实现引用自定义调用

Bean调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.springdemo.entity.SpEL;

import com.example.springdemo.entity.SpEL.pojo.theBicycleFactoryInfo;
import com.example.springdemo.entity.SpEL.pojo.theBicycleInfo;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class theBeanSpEL {
public static void main(String[] args) {
//创建一个bean工厂监听器
DefaultListableBeanFactory defaultListableBeanFactory=new DefaultListableBeanFactory();


//创建对应的对象
theBicycleInfo theBicycleInfo=new theBicycleInfo();
theBicycleInfo.setName("Charon");
theBicycleInfo.setAge(22);
theBicycleInfo.setDescription("this is why we play");
theBicycleInfo.setTheBicycleType("The normal road");
theBicycleFactoryInfo beiJing = theBicycleFactoryInfo.builder().FactoryLocation("BeiJing").factoryName("S-works").factoryPrice(2333).build();
theBicycleInfo.setTheBicycleFactoryInfo(beiJing);


//注册相关工厂bean(单例注册操作)
defaultListableBeanFactory.registerSingleton("theBicycleInfo",theBicycleInfo);

//创建语法上下文操作
StandardEvaluationContext evaluationContext=new StandardEvaluationContext();
ExpressionParser expressionParser=new SpelExpressionParser();
evaluationContext.setBeanResolver(new BeanFactoryResolver(defaultListableBeanFactory));

System.out.println(expressionParser.parseExpression("@theBicycleInfo").getValue(evaluationContext, theBicycleInfo.class));
}
}

内联数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.springdemo.entity.SpEL;

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

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

public class ListSpEL {
public static void main(String[] args) {
//创建相关的操作去进行解析相关的操作
ExpressionParser expres=new SpelExpressionParser();
List<Integer> theSpElements=expres.parseExpression("{1,3,45,35,6416,417}").getValue(List.class);
assert theSpElements != null;
theSpElements.forEach(System.out::println);
System.out.println(theSpElements.getClass().getTypeName());


List<List<Integer>> theDoubleArrayList=expres.parseExpression("{{3+2,417},{2+3,3333}}").getValue(List.class);
System.out.println(theDoubleArrayList);


int [] theAnother=expres.parseExpression("{1,2,321,3,123}").getValue(int[].class);
System.out.println(Arrays.toString(theAnother));

int[] theNewAnother=expres.parseExpression("new int[3]").getValue(int[].class);
theNewAnother[0]=98;
System.out.println(Arrays.toString(theNewAnother));

int[][] theDoubleArray=expres.parseExpression("new int[2][3]").getValue(int[][].class);
theDoubleArray[0][1]=33;
System.out.println(theDoubleArray[0][1]);
}
}

集合,字典,访问修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.example.springdemo.entity.SpEL;

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Stack;

public class CollectionSpELTest {
public static void main(String[] args) {
//创建一个语法解析器
ExpressionParser expressionParser=new SpelExpressionParser();
//获取单个数组的元素变量操作,内连表达式操作
System.out.println(expressionParser.parseExpression("{2,3,34}[2]").getValue(int.class));

Collection<Integer> collection=new HashSet<>();
collection.add(3);
collection.add(23);
collection.add(417);
System.out.println(collection);
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("collection",collection);
System.out.println(expressionParser.parseExpression("#collection").getValue(evaluationContext,Collection.class));

Stack<Integer> stack=new Stack<>();
stack.push(3);
stack.push(22);
stack.push(98);
evaluationContext.setVariable("stack",stack);
System.out.println(expressionParser.parseExpression("#stack").getValue(evaluationContext,Stack.class).peek());

//利用EL表达式来修改相关元素的参数值

ArrayList<Integer> arrayList=new ArrayList<>();
arrayList.add(3);
arrayList.add(22);
arrayList.add(417);
evaluationContext.setVariable("array",arrayList);
//注意应用程序上下文之间的空间操作理解,此处的上下文空间是需要进行逻辑连接的
expressionParser.parseExpression("#array[0]").setValue(evaluationContext,33);
System.out.println(expressionParser.parseExpression("#array[0]").getValue(evaluationContext, int.class));
}
}

如果存在需要修改其中变量的值操作,一定是需要使用标准对象来进行操作的,千万不能使用元类进行操作

投影表达式/选择表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.springdemo.entity.SpEL;

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class theShdow {
public static void main(String[] args) {
//创建一个数组
List<Integer> theArrayList=new ArrayList<>();
theArrayList.add(3);
theArrayList.add(418);
theArrayList.add(78);
theArrayList.add(33);
theArrayList.add(276);
//标准词法解析器
ExpressionParser expres=new SpelExpressionParser();
EvaluationContext evaluationContext = new StandardEvaluationContext();
evaluationContext.setVariable("collection",theArrayList);
//投影表达式操作,对每一个数组变量进行添加操作,并且实现相关的操作理解
Collection value = expres.parseExpression("#collection.![(#this+1)*99]").getValue(evaluationContext, Collection.class);
System.out.println(value);
//不能进行持久化操作,需要对相关的上下文进行重新理解
evaluationContext.setVariable("collection",value);
Collection theSelect=expres.parseExpression("#collection.?[#this > 3000]").getValue(evaluationContext,Collection.class);
System.out.println(theSelect);


//投影表达式与选择表达式进行联合理解操作

System.out.println(expres.parseExpression("#collection.?[#this >4000].![#this+9999999]").getValue(evaluationContext,Collection.class));
}
}

image-20231125231724786

表达式模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.springdemo.entity.SpEL;

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

public class parserContext {
public static void main(String[] args) {
//第一步依然是执行语法解析器操作
ExpressionParser expression=new SpelExpressionParser();
//定义模板类操作实现
ParserContext parserContext=new ParserContext() {
@Override
public boolean isTemplate() {
return true;
}

@Override
public String getExpressionPrefix() {
return "&{";
}

@Override
public String getExpressionSuffix() {
return "}";
}
};
String template="&{'Zeus'},&{'Apollo'},&{'Gods'},&{#jack}";
//创建标准上下文操作
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("jack","Artemis");
Expression expression1 = expression.parseExpression(template, parserContext);
System.out.println(expression1.getValue());
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.example.springdemo.entity.SpEL;

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

public class theTemplateSpEL {
public static void main(String[] args) {
//创建语法解析器
ExpressionParser expr=new SpelExpressionParser();
//构建模板表达式操作
ParserContext parserContext=new ParserContext() {
@Override
public boolean isTemplate() {
return true;
}

@Override
public String getExpressionPrefix() {
return "#{";
}

@Override
public String getExpressionSuffix() {
return "}";
}
};
//利用此处的模板操作也需要进行字符串的框选吗?
String template="#{'Hello'},#{'World'},#{#some}";
//关键式如何对此处的操作进行理解?使用模板操作还能进行一些变量的设置操作吗
Expression expression = expr.parseExpression(template, parserContext);
//利用上下文是无法对模板类进行解析赋值操作的
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("some","queen");
System.out.println(expression.getValue(evaluationContext));
}
}

关于Spring中实现的SpEL表达式操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.example.springdemo.Configuration;


import com.example.springdemo.entity.*;
import com.example.springdemo.pojoInterface.theComputerType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;


//定义配置文件操作
//实现异步操作
@EnableAsync
//实现
@EnableScheduling
@Configuration
//多个组件之间的扫描操作
@ComponentScans({
@ComponentScan("com.example.springdemo.entity"),
@ComponentScan("com.example.springdemo.entity.theAware"),
@ComponentScan("com.example.springdemo.entityWatchContruct"),
@ComponentScan("com.example.springdemo.entity.Task"),
@ComponentScan("com.example.springdemo.entity.Listener"),
@ComponentScan("com.example.springdemo.entity.SpEL"),
@ComponentScan("com.example.springdemo.entity.SpEL.pojo")
})
@PropertySource("classpath:theProperties.properties")
public class theConfiguration {

}

传入配置文件

1
@PropertySource("classpath:theProperties.properties")

[【文字+图示】Java项目中类路径classpath具体指的是哪个路径_java中的类路径是指什么_超周到的程序员的博客-CSDN博客](https://blog.csdn.net/m0_46360532/article/details/114498540#:~:text=类路径classpath指的是编译后路径即%3A本项目 [或模块目录]%2Ftarget%2F,[项目或模块名]%2FWEB-INF%2Fclasses如下图: java目录中的文件和recource目录中的文件经过编译后,都会放到WEB-INF%2Fclasses目录下:_java中的类路径是指什么)

image-20231121114958560

image-20231125233332716

配置文件

1
king=fbcd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.springdemo.entity.SpEL;


import jakarta.annotation.Resource;
import jakarta.annotation.security.DenyAll;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("theValue")
@Data
public class theValue {
String name;
//实现参数值的注入操作
public theValue(@Value("${king}")String name){
this.name = name;
}
}

如果我们在项目之中也想形成自定义理解呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.springdemo.entity.SpEL;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.stereotype.Component;

@Component
public class theComponentTest implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//获取相关的bean表达式解析器,这种解析器是存在与生命周期的前部分的操作的
BeanExpressionResolver beanExpressionResolver = beanFactory.getBeanExpressionResolver();
//如果相关组件进行了注册操作,那么进行相关的模板语法解析
if (beanExpressionResolver instanceof StandardBeanExpressionResolver){
StandardBeanExpressionResolver standardBeanExpressionResolver= (StandardBeanExpressionResolver)beanExpressionResolver;
standardBeanExpressionResolver.setExpressionPrefix("&{");
standardBeanExpressionResolver.setExpressionSuffix("}");
}
}
}

自动获取相关的bean表达式解析对象,通过工厂方法进行获取,然后判断获取到的对象是否是继承与标准对象解析,如何理解此处,那是因为如果存在非标准解析类操作,所做的事情是完全不一样的,上面我有提到过!通过标准类直接解析相关符号,注意前置后置千万不能写错了,这里是一个易错点!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.context.expression;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanExpressionException;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.expression.spel.support.StandardTypeLocator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
* Standard implementation of the
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
* interface, parsing and evaluating Spring EL using Spring's expression module.
*
* <p>All beans in the containing {@code BeanFactory} are made available as
* predefined variables with their common bean name, including standard context
* beans such as "environment", "systemProperties" and "systemEnvironment".
*
* @author Juergen Hoeller
* @since 3.0
* @see BeanExpressionContext#getBeanFactory()
* @see org.springframework.expression.ExpressionParser
* @see org.springframework.expression.spel.standard.SpelExpressionParser
* @see org.springframework.expression.spel.support.StandardEvaluationContext
*/
public class StandardBeanExpressionResolver implements BeanExpressionResolver {

/** Default expression prefix: "#{". */
public static final String DEFAULT_EXPRESSION_PREFIX = "#{";

/** Default expression suffix: "}". */
public static final String DEFAULT_EXPRESSION_SUFFIX = "}";


private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;

private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;

private ExpressionParser expressionParser;

private final Map<String, Expression> expressionCache = new ConcurrentHashMap<>(256);

private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = new ConcurrentHashMap<>(8);

private final ParserContext beanExpressionParserContext = new ParserContext() {
@Override
public boolean isTemplate() {
return true;
}
@Override
public String getExpressionPrefix() {
return expressionPrefix;
}
@Override
public String getExpressionSuffix() {
return expressionSuffix;
}
};


/**
* Create a new {@code StandardBeanExpressionResolver} with default settings.
*/
public StandardBeanExpressionResolver() {
this.expressionParser = new SpelExpressionParser();
}

/**
* Create a new {@code StandardBeanExpressionResolver} with the given bean class loader,
* using it as the basis for expression compilation.
* @param beanClassLoader the factory's bean class loader
*/
public StandardBeanExpressionResolver(@Nullable ClassLoader beanClassLoader) {
this.expressionParser = new SpelExpressionParser(new SpelParserConfiguration(null, beanClassLoader));
}


/**
* Set the prefix that an expression string starts with.
* The default is "#{".
* @see #DEFAULT_EXPRESSION_PREFIX
*/
public void setExpressionPrefix(String expressionPrefix) {
Assert.hasText(expressionPrefix, "Expression prefix must not be empty");
this.expressionPrefix = expressionPrefix;
}

/**
* Set the suffix that an expression string ends with.
* The default is "}".
* @see #DEFAULT_EXPRESSION_SUFFIX
*/
public void setExpressionSuffix(String expressionSuffix) {
Assert.hasText(expressionSuffix, "Expression suffix must not be empty");
this.expressionSuffix = expressionSuffix;
}

/**
* Specify the EL parser to use for expression parsing.
* <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser},
* compatible with standard Unified EL style expression syntax.
*/
public void setExpressionParser(ExpressionParser expressionParser) {
Assert.notNull(expressionParser, "ExpressionParser must not be null");
this.expressionParser = expressionParser;
}


@Override
@Nullable
public Object evaluate(@Nullable String value, BeanExpressionContext beanExpressionContext) throws BeansException {
if (!StringUtils.hasLength(value)) {
return value;
}
try {
Expression expr = this.expressionCache.get(value);
if (expr == null) {
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
this.expressionCache.put(value, expr);
}
StandardEvaluationContext sec = this.evaluationCache.get(beanExpressionContext);
if (sec == null) {
sec = new StandardEvaluationContext(beanExpressionContext);
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
sec.addPropertyAccessor(new BeanFactoryAccessor());
sec.addPropertyAccessor(new MapAccessor());
sec.addPropertyAccessor(new EnvironmentAccessor());
sec.setBeanResolver(new BeanFactoryResolver(beanExpressionContext.getBeanFactory()));
sec.setTypeLocator(new StandardTypeLocator(beanExpressionContext.getBeanFactory().getBeanClassLoader()));
sec.setTypeConverter(new StandardTypeConverter(() -> {
ConversionService cs = beanExpressionContext.getBeanFactory().getConversionService();
return (cs != null ? cs : DefaultConversionService.getSharedInstance());
}));
customizeEvaluationContext(sec);
this.evaluationCache.put(beanExpressionContext, sec);
}
return expr.getValue(sec);
}
catch (Throwable ex) {
throw new BeanExpressionException("Expression parsing failed", ex);
}
}

/**
* Template method for customizing the expression evaluation context.
* <p>The default implementation is empty.
*/
protected void customizeEvaluationContext(StandardEvaluationContext evalContext) {
}

}

总说:

SpEL所带来的程序与数据分离,逻辑配置与约定分离的操作,是贯穿整个Spring框架的学习路程的,学习完整个表达式之后,关于整个框架的理解,上了一个档次,也为之前所获取到的知识点升华了许多,总的来说,梳理好,抽象好整个Project的的逻辑比单纯学一门操作来的实在,并且深刻,这就是SpEL表达式,一个涉及范围非常广的表达式,当然了可能内部源码我还没有分析透,希望以后继续学习