承德很好的网络建站,网站说明页命名,百度静态网站,做网站需要申请专利吗Spring 表达语言#xff08;SpEL#xff09;#xff0c;支持在运行时查询和操作对象图#xff0c;可以用于数据绑定、属性访问、方法调用等。使用SpEL可以简化代码并提高应用程序的可维护性。
1 概览
SpelExpressionParser是SpEL的一个核心组件#xff0c;负责解析和编译… Spring 表达语言SpEL支持在运行时查询和操作对象图可以用于数据绑定、属性访问、方法调用等。使用SpEL可以简化代码并提高应用程序的可维护性。
1 概览
SpelExpressionParser是SpEL的一个核心组件负责解析和编译SpEL表达式。Expression 是根据上下文计算的表达式封装了之前分析的表达式的详细信息为表达式计算提供接口。
public static void main(String[] args) {SpelExpressionParser parser new SpelExpressionParser();String str1 parser.parseExpression(hello.concat( SpEL)).getValue(String.class); // hello SpELInteger sum parser.parseExpression(1 99).getValue(Integer.class); // 100}
1.1 EvaluationContext
是SpEL中用于计算表达式的上下文提供了一个环境使得SpEL表达式可以访问和操作其中的变量和对象。在Spring上下文中通常不要手动创建EvaluationContext,容器会自动创建并管理 包含多个对象 可以是任何Java对象供表达式引用和操作。 根对象 只有一个根对象是上下文中的核心对象其他对象可以通过根对象进行访问。 变量解析 可以在其中设置和获取变量的值会根据其中的值来解析和执行表达式。 类型转换 在执行SpEL表达式时可以将一种类型的值转换为另一种类型。通过ConversionService 来完成转换 反射机制 通常使用反射机制来操作对象可以动态地访问和调用对象的属性和方法。 性能优化 会在其内部缓存反射信息。
表 EvaluationContext 提供的功能
其有两个实现
StandardEvaluationContext提供了全套的SpEL语言功能和配置选项。
SimpleEvaluationContext仅支持SpEL语法的子集不包括Java类型引用、构造函数和bean引用。会更安全。
public static void testContext() {User user new User(hmf);StandardEvaluationContext context new StandardEvaluationContext(user);ListString strList new ArrayList();strList.add(hello);strList.add(java);context.setVariable(list,strList);SpelExpressionParser parser new SpelExpressionParser();String username parser.parseExpression(username).getValue(context, String.class);System.out.println(parser.parseExpression(#list).getValue(context)); // [hello, java]System.out.println(username); // hmf}
1.2 编译器
SpEL 表达式通常在运行期间通过解释器进行进行执行但是这样性能不是很好。SpEL 编译器是对表达式进行编译在运行前或运行中将表达式生成一个Java类。注意编译器适合表达式中的类型保持稳定的情况下使用 OFF 默认模式编译器被关闭。 IMMEDIDATE 表达式会尽快被编译通常发生在第一次解释评估之后。 MIXED 表达式会在解释模式和编译模式之间静默转换。一开始表达式会进行解释执行经过一定数量的解释执行后它们会切换到编译模式。如果编译模式出现问题例如类型更改则表达式会自动切回解释模式一段时间后可能会编译成新的格式并切回到它。
表 SpEL编译器的三种模式
注意SpEL 要在运行时才能发现错误编译阶段不能发现错误。
1.2.1 MIXED模式的不足
1前期MIXED会解释执行效率可能会比编译执行慢。
2MIXED 可能会自动切回解释模式这样虽能保证表达式的可用性但也导致了性能上的不稳定每次切换到解释模式时都需要重新进行解释执行这可能会比编译执行更耗时。
1.2.2 编译模式下的限制
以下情况的表达式不能在编译模式下执行
涉及赋值。依赖转换服务的表达式。使用自定义解析器或访问器。使用选择或投影表达式例如#{}、![]。
1.3 在Bean定义中使用
在IoC容器中定义Bean时可以使用SpEL 表达式来给属性赋值。语法为#{表达式}。
注解模式
Value(#{hello.length()})
XML配置
property namename value#{hello.concat(java)}/
2 常用语法
SpEL 可以访问属性、调用方法、执行算术和逻辑运算、处理集合和数值及使用正则表达式等。 访问属性 使用点号.来访问对象的属性。#{person.name},也可访问嵌套属性。#{person.address.city} 访问数值、列表和集合 使用方括号[]来访问其元素。#{list[0]}、#{array[0]}、#{map[‘key’]} 调用方法 使用点号(.)或方括号([])来调用方法。#{person.setName(‘hello’)} 运算符 算术运算符、比较运算符、逻辑运算符、三元运算符。 正则表达式 使用关键字“matches”。 #{name matches ‘.*word.’} 列表投影和选择 ? 进行列表投影选择符合条件的元素^ 选择第一个元素$ 选择最后一个元素。 #{list.?[#this 10]}、#{list.^[#this 10]} 变量引用 可以直接引用bean, 通过bean名 来访问这个bean (解析器需要与容器关联)。#{myBean}或者EvaluationContext环境变量。 安全导航操作符 使用? 进行安全导航避免空指针异常。#{person?.address?.city}、#{person?.name?:‘无名’} 类型运算符 使用T() 告诉表达式将其作为类来处理。#{T(java.lang.String).valueOf(123)}
表 SpEL 的常用语法
public class SpELTest2 {public static void main(String[] args) {Person person new Person(黄先生, null);SpelExpressionParser parser new SpelExpressionParser();// 访问属性System.out.println(parser.parseExpression(name).getValue(person)); // 黄先生// 访问数值、列表和集合MapString,Object map new HashMap();map.put(username,hmf);ListMapString,Object list new ArrayList();list.add(map);System.out.println(parser.parseExpression([0][username]).getValue(list));// hmf// 调用方法parser.parseExpression(showInfo).getValue(person); // Person{name黄先生, addressnull}// 运算符System.out.println(parser.parseExpression(1 99 43 黄先生 name).getValue(person)); // true// 正则表达式System.out.println(parser.parseExpression(hello word! matches .*hello\\b.*).getValue()); // true// 列表投影和选择Integer[] numArray new Integer[]{12,5,7,66,22,34,1};ListInteger numList Arrays.asList(numArray);System.out.println(parser.parseExpression(?[#this 10]).getValue(numList)); // [12, 66, 22, 34]System.out.println(parser.parseExpression(^[#this 10]).getValue(numList)); // 12System.out.println(parser.parseExpression($[#this 10]).getValue(numList)); // 34// 安全导航操作符System.out.println(parser.parseExpression(address?.city).getValue(person)); // null// 类型运算符System.out.println(parser.parseExpression(T(java.lang.Math).random()).getValue()); // 0.7829801028898056}private static class Person {private String name;private Address address;public Person(String name, Address address) {this.name name;this.address address;}public String getName() {return name;}public void setName(String name) {this.name name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address address;}public void showInfo() {System.out.println(this);}Overridepublic String toString() {return Person{ name name \ , address address };}}private static class Address {private String province;private String city;public Address(String province, String city) {this.province province;this.city city;}public String getProvince() {return province;}public void setProvince(String province) {this.province province;}public String getCity() {return city;}public void setCity(String city) {this.city city;}}}