Spring 中表达式语⾔spring-expression 简单使⽤
前⾔
Spring Expression Language (简称 SpEL )是⼀个⽀持查询和操作运⾏时对象导航图功能的强⼤的表达式语⾔,它的语法类似于传统 EL(如jsp 中的EL 表达式)
,
但提供额外的功能,最出⾊的就是函数调⽤和简单字符串的模板函数。SpEL 作为Spring 框架的基础,但并不依赖于Spring 容器,可以独⽴使⽤。
简单使⽤
引⼊maven 依赖
简单字⾯量
⽀持字符串,⽇期,数值(整型,浮点型,⼗六进制),布尔等类型
输出结果为
变量引⽤
通过#'变量名'的⽅式来使⽤变量
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//解析表达式并获取结果
System.out.println(expressionParser.parseExpression("'hello'").getValue());
System.out.println(expressionParser.parseExpression("123").getValue());
System.out.println(expressionParser.parseExpression("12.34").getValue());
System.out.println(expressionParser.parseExpression("10e2").getValue());
System.out.println(expressionParser.parseExpression("true").getValue());
System.out.println(expressionParser.parseExpression("new java.util.Date()").getValue());
hello
123
12.34
1000.0
true
Sat Sep 25 19:39:38 CST 2021
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//创建数据上下⽂
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
//设置变量
evaluationContext.setVariable("a", 12);
spring ioc注解evaluationContext.setVariable("b", 34);
evaluationContext.setVariable("c", 56);
//解析表达式
System.out.println(expressionParser.parseExpression("#a+#b-#c").getValue(evaluationContext));
输出为
-10
对象的属性和⽅法
定义⼀个普通bean
public class User {
private String name;
public User(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
通过对象.属性的⽅式来引⽤
/
/创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//创建数据上下⽂
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); evaluationContext.setVariable("user", new User("lisi"));
System.out.println(expressionParser.parseExpression("#user.name").getValue(evaluationContext)); System.out.println(expressionParser.parseExpression("#Name()").getValue(evaluationContext));
输出为
lisi
lisi
数组,集合,map
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//创建数据上下⽂
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
//设置数组变量
evaluationContext.setVariable("users", new User[]{new User("Tom")});
//设置集合变量
evaluationContext.setVariable("userList", Collections.singletonList(new User("Mary")));
//设置map变量
evaluationContext.setVariable("userMap", Collections.singletonMap("u123", new User("u123")));
System.out.println(expressionParser.parseExpression("#users[0].name").getValue(evaluationContext)); System.out.println(expressionParser.parseExpression("#userList[0].name").getValue(evaluationContext)); System.out.println(expressionParser.parseExpression("#userMap['u123'].name").getValue(evaluationContext));
输出为
Tom
Mary
u123
普通⽅法调⽤
和在Java中使⽤没有区别
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
System.out.println(expressionParser.parseExpression("'hello'.substring(2)").getValue());
输出为
llo
操作符
⽀持关系操作符(⼤于⼩于等于),逻辑操作符(and or not),算数操作符(加减乘除)
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
System.out.println(expressionParser.parseExpression("1 < 4").getValue());
System.out.println(expressionParser.parseExpression("1 < 4 and 5 > 9 ").getValue());
System.out.println(expressionParser.parseExpression("1 + 3 - 5").getValue());
引⽤IOC容器中的bean
定义bean的配置⽂件
import t.annotation.Bean;
import t.annotation.Configuration;
@Configuration
public class BeanConfig {
@Bean
public User user() {
return new User("lisi");
}
}
默认⽀持#{}的格式来引⽤bean
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//创建数据上下⽂
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
//创建IOC容器上下⽂
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
//创建bean表达式上下⽂
BeanExpressionContext beanExpressionContext = new BeanExpressionContext((ConfigurableBeanFactory) AutowireCapableBeanFactory(), null); evaluationContext.setRootObject(beanExpressionContext);
//添加属性访问器从IOC容器中获取bean
evaluationContext.addPropertyAccessor(new BeanExpressionContextAccessor());
System.out.println(expressionParser.parseExpression("#{user.name}", new TemplateParserContext()).getValue(evaluationContext));
输出为
lisi
@Value注解
我们在项⽬中很多地⽅都会⽤到@Value注解
@Value("${name}")
private String name;
@Value("#{person.name}")
private String personName;
解析@Value注解的过程就会使⽤到SpEL
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = solveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = DependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
//字符串类型就表⽰是@Value注解注⼊
if (value instanceof String) {
// 使⽤StringValueResolver处理${}占位符
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
//处理bean表达式,#{}这种格式
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
vertIfNecessary(value, type, TypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support
return (Field() != null ?
}
}
...
.
..
}
@Nullable
protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) { if (this.beanExpressionResolver == null) {
return value;
}
Scope scope = null;
if (beanDefinition != null) {
String scopeName = Scope();
if (scopeName != null) {
scope = getRegisteredScope(scopeName);
}
}
return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
}
}
默认使⽤的beanExpressionResolver为StandardBeanExpressionResolver。
参考
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论