文章目录
1、 spring-expression el表达式支持
官网文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions
1.1 简单使用示例
1、maven文件依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.0.10.RELEASE</version>
</dependency>
2、示例代码
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import java.util.Arrays;
import java.util.List;
/**
* @author yinyuming
* @date 2021-06-10 15:51
*/
public class SpringTest {
public static void main(String[] args) {
//详细见:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions-language-ref
//表达式
SpelExpressionParser parser = new SpelExpressionParser();
//1、数值类
System.out.println(parser.parseExpression("'真好!'").getValue(String.class));
System.out.println(parser.parseExpression("1.222").getValue(Double.class));
System.out.println(parser.parseExpression("0x7FFFFFFF").getValue(Long.class));
System.out.println(parser.parseExpression("true").getValue(Boolean.class));
//2、对象,数组,索引等
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
String[] array = new String[]{"abc1","abc2","abc3"};
List<String> list = Arrays.asList("abc1", "abc2", "abc3");
class A{
public String name;
public A(String a) {
this.name = a;
}
}
List<A> objects = Arrays.asList(new A("a"));
System.out.println(parser.parseExpression("[0]").getValue(context, list, String.class));
System.out.println(parser.parseExpression("[1]").getValue(context, array, String.class));
System.out.println(parser.parseExpression("[0].name").getValue(context, objects, String.class));
System.out.println(parser.parseExpression("{1,2,3,4}").getValue(context, List.class));
//3、关系运算符
// evaluates to true, lt( <), gt( >), le( <=), ge( >=), eq( ==), ne( !=), div( /), mod( %), not( !).
System.out.println(parser.parseExpression("2 gt 2").getValue());
System.out.println(parser.parseExpression("2 == 2").getValue());
System.out.println(parser.parseExpression("2 < -5.0").getValue());
System.out.println(parser.parseExpression("'black' < 'block'").getValue());
//4、逻辑运算符,and( &&),or( ||),not( !)
System.out.println(parser.parseExpression("true and false").getValue());
System.out.println(parser.parseExpression("true || false").getValue());
//5、数学运算符,加法(+),减法 ( -)、乘法 ( *) 和除法 ( /),模数 ( %) 和指数幂 ( ^) 运算符
System.out.println(parser.parseExpression("1 + 1").getValue(Integer.class));
System.out.println(parser.parseExpression("2 * 3").getValue(Integer.class));
System.out.println(parser.parseExpression("2^5").getValue(Integer.class));
//6、类型
System.out.println(parser.parseExpression("T(java.util.Date)").getValue(Class.class));
}
}
1.2 应用
可以让你的某些自己的配置文件也支持spring el表达式解析,
1.2.1 自定义注解使用spring的el表达式
package com.yym.frame.spring.el;
/**
* @author yinyuming
* @date 2021-08-12 10:19
*/
public @interface MyAnnotation {
String key() default "";
String name() default "";
}
package com.yym.frame.spring.el;
/**
* @author yinyuming
* @date 2021-08-12 10:16
*/
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* 分布式锁切面
*
* @author HuangYong
*/
@Slf4j
@Aspect
public class AspectElParam {
public static void main(String[] args) {
AspectElParam aspectElParam = new AspectElParam();
String valBySpEL = aspectElParam.getValBySpEL("#b+#a", new String[]{"a", "b"}, new Object[]{1, 2});
System.out.println("结果valBySpEL=" + valBySpEL);
}
/**
* 用于SpEL表达式解析.
*/
private SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
/**
* 用于获取方法参数定义名字.
*/
private DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
@Around("@within(myAnnotation) || @annotation(myAnnotation)")
public Object aroundLock(ProceedingJoinPoint point, MyAnnotation myAnnotation) throws Throwable {
if (myAnnotation == null) {
// 获取类上的注解
myAnnotation = point.getTarget().getClass().getDeclaredAnnotation(MyAnnotation.class);
}
String key = myAnnotation.key();
if (StringUtils.isEmpty(key)) {
throw new RuntimeException("key el param is null");
}
if (key.contains("#")) {
MethodSignature methodSignature = (MethodSignature) point.getSignature();
//获取方法参数值
Object[] args = point.getArgs();
key = getValBySpEL(key, nameDiscoverer.getParameterNames(methodSignature.getMethod()), args);
}
try {
log.info("获取到注解上,名字=" + myAnnotation.name() + ",el表达式的key=" + key);
//加锁
return point.proceed();
} finally {
}
}
/**
* 解析spEL表达式
*/
private String getValBySpEL(String spEL, String[] paramNames, Object[] args) {
//获取方法形参名数组
if (paramNames != null && paramNames.length > 0) {
Expression expression = spelExpressionParser.parseExpression(spEL);
// spring的表达式上下文对象
EvaluationContext context = new StandardEvaluationContext();
// 给上下文赋值
for (int i = 0; i < args.length; i++) {
context.setVariable(paramNames[i], args[i]);
}
return expression.getValue(context).toString();
}
return null;
}
}
使用效果如下
@MyAnnotation (name="my_choose_name",key="#a+#b")
public void getName(String a, String b){
}
1.2.2 spring配置中使用spring的el表达式
spring:
cloud:
nacos:
discovery:
enabled: true
server-addr: http://localhost
namespace: dev
group: DEFAULT_GROUP
username: root
password: 123456
sentinel:
datasource:
#入口调用限制
entry-ds:
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
username: ${spring.cloud.nacos.discovery.username}
password: ${spring.cloud.nacos.discovery.password}