Spring SpEL表达式

Spring SpEL表达式

简单使用

导入依赖

 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.3.20</version>
      <scope>compile</scope>
  </dependency>

简单解析并使用

public class test {
    public static void main(String[] args) {
    	//spel解析器
        SpelExpressionParser spel = new SpelExpressionParser();
        //解析spel表达式 返回Expression 对象(计算)
        Expression exp = spel.parseExpression("'Hello'.toUpperCase()");
        //获取值
        String value = exp.getValue(String.class);
        System.out.println(value);//输出HELLO
    }
}

关于对象的简单使用(修改对象的属性)

public class test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("ck");
        user.setAge(18);
        SpelExpressionParser spel = new SpelExpressionParser();
        //多了EvaluationContext 接口
        EvaluationContext standardEvaluationContext = new StandardEvaluationContext(user);
        spel.parseExpression("age").setValue(standardEvaluationContext, 55);
        System.out.println(user.getAge());
    }
}

SpEL编译器

重复编译的设定

如果相同的表达式多次使用,每次都要解析浪费资源。可以设置让经常使用的转换为字节码。

SpelParserConfiguration spelParserConfiguration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, test.class.getClassLoader());
SpelExpressionParser spelExpressionParser = new SpelExpressionParser(spelParserConfiguration);
  • IMMEDIATE 立即启动编译,在第二次表达式取值时才会启用编译

  • OFF 默认,不启动编译
    在这里插入图片描述

  • MIXED 混合型 在解释形和编译型互相切换 在解释了一定数量后(100),变成编译形

SpEL基础表达式

文本字符解析

支持字符串,日期,数字,布尔,null
字符串用单引号包住或者 "包住,单引号字符’

public class test {
    public static void main(String[] args) {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        String value = (String)spelExpressionParser.parseExpression("'hello'").getValue();
        Double value1 = (Double)spelExpressionParser.parseExpression("6.2333E+4").getValue();
        int value2 = (Integer)spelExpressionParser.parseExpression("0x7FFFFFFF").getValue();
        boolean value3 = (Boolean)spelExpressionParser.parseExpression("true").getValue();
        Object value4 = spelExpressionParser.parseExpression("null").getValue();
    }
}

对象属性解析

public class test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("陈克");
        user.setAge(18);
        user.setPlaceOfBirsth(new placeOfBirsth("中国","福州"));
        SpelExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(user);
        //基本属性值获取
        String name = (String)parser.parseExpression("name").getValue(context);
        Integer age = (Integer)parser.parseExpression("age + 10").getValue(context);
        System.out.println(name);//陈克
        System.out.println(age);//28
        //嵌套对象属性值获取
        String city = (String)parser.parseExpression("placeOfBirsth.city").getValue(context);
        System.out.println(city);//中国
    }
}

数组,集合形式解析

不支持多维数组的初始化

public class test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("陈克");
        user.setAge(18);
        user.setPlaceOfBirsth(new placeOfBirsth("中国","福州"));
        SpelExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(user);
        //一维数组的 创建和初始化
        int[] array = (int[])parser.parseExpression("new int[]{1,2,3}").getValue(context);
        //多维数组的创建
        int[][] array1 = (int[][])parser.parseExpression("new int[2][3]").getValue();
        //List
        List list = (List)parser.parseExpression("{1,2,3,4}").getValue();
        //Liat中List
        List list1 = (List)parser.parseExpression("{{'a','b'},{'x','y'}}").getValue();
        //Map
        Map map = (Map)parser.parseExpression("{userName:'tom',credite:100}").getValue();
        //list中的Map
        List list3 = (List)parser.parseExpression("{{userName:'tom',credite:100},{userName:'tom1',credite:200}}").getValue();
        //map中的List
        Map map1 = (Map)parser.parseExpression("{userName:{'a','b'},credite:{'c','d'}}").getValue();
        //从数组,list,map中取出值(从对象中取出 ints为实体类的变量名)
        int value = (Integer)parser.parseExpression("ints[0]").getValue(context);
        String list = (String)parser.parseExpression("list[0]").getValue(context);
        String map = (String)parser.parseExpression("map['name']").getValue(context);
    }
}

方法解析

可以调用对象所有的可用的实例方法。静态方法。可变参方法

实体类

@Data
public class User {
    private String name;
    private Integer age;
    private placeOfBirsth placeOfBirsth;
    private List list;
    private int[] ints;
    private Map map;

    public static void say(String mes)
    {
        System.out.println(mes);
    }

    public void sleep(String mes,String... args)
    {
        System.out.println(mes + Arrays.toString(args));
    }
}

使用

public class test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("陈克");
        user.setAge(18);
        user.setPlaceOfBirsth(new placeOfBirsth("中国","福州"));
        SpelExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(user);
        //调用实例方法
        String name = parser.parseExpression("getName()").getValue(context,String.class);
        //调用静态方法
        String say = parser.parseExpression("say('我说')").getValue(context,String.class);
        //调用可变参方法
        String sleep = parser.parseExpression("sleep('我说','2','2')").getValue(context,String.class);

    }
}

关系操作符

public class test1 {
    public static void main(String[] args) {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //关系操作符
        Boolean value = spelExpressionParser.parseExpression("2==2").getValue(Boolean.class);
        Boolean value1 = spelExpressionParser.parseExpression("2>5").getValue(Boolean.class);
        //string比较(不支持 但是spel支持)
        Boolean value2 = spelExpressionParser.parseExpression("'不'>'持'").getValue(Boolean.class);
        //instanceof
        Boolean value3 = spelExpressionParser.parseExpression("'不' instanceof T(String)").getValue(Boolean.class);
        //正则表达式
        Boolean value4 = spelExpressionParser.parseExpression(" '8' matches '^[1-9]d*$'").getValue(Boolean.class);
        System.out.println(value4);
    }
}

逻辑操作符

  • 与操作(&& 或者 and)
  • 或操作(|| 或者 or)
  • 非(!)
public class test1 {
    public static void main(String[] args) {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //逻辑操作符
        Boolean value = spelExpressionParser.parseExpression("true and false").getValue(Boolean.class);
        Boolean value1 = spelExpressionParser.parseExpression("true && false").getValue(Boolean.class);
        Boolean value2 = spelExpressionParser.parseExpression("true || false").getValue(Boolean.class);
        Boolean value3 = spelExpressionParser.parseExpression("true or false").getValue(Boolean.class);
        Boolean value4 = spelExpressionParser.parseExpression("!true").getValue(Boolean.class);
        System.out.println(value4);
    }
}

算术运算符

在这里插入图片描述

public class test1 {
    public static void main(String[] args) {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //逻辑操作符
        Integer value = spelExpressionParser.parseExpression("1 + 1").getValue(Integer.class); //1
        Integer value1 = spelExpressionParser.parseExpression("3 * 5.658").getValue(Integer.class); //16
        Integer value2 = spelExpressionParser.parseExpression("10 / 3").getValue(Integer.class); //3
        Integer value3 = spelExpressionParser.parseExpression("10 % 3").getValue(Integer.class); //1
        Integer value4 = spelExpressionParser.parseExpression("10^3 ").getValue(Integer.class); //1000
    }
}

安全导航符

类似java8 的 Optional

用?号来判断对象是否为null。为null就返回字符串null,而不是空指针

public class test1 {
    public static void main(String[] args) {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        User user = new User();
        user.setName("ck");
        user.setAge(15);
       // user.setBody(new Body("bp","bt"));
        StandardEvaluationContext context = new StandardEvaluationContext(user);

        //逻辑操作符
        String value = spelExpressionParser.parseExpression("body?.hand").getValue(context,String.class);
        System.out.println(value);
    }
}

三元操作符

Integer value = spelExpressionParser.parseExpression("name == 'ck'? age+10:age").getValue(context,Integer.class);

Elvis操作符

三元表达式类似的简写
如果name不为null则取原来的值,如果为null取value

 String value = spelExpressionParser.parseExpression("name?:'名字为空'").getValue(context,String.class);

赋值,类型,构造器,变量

赋值
public class test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("陈克");
        user.setAge(18);
        user.setPlaceOfBirsth(new placeOfBirsth("中国","福州"));
        SpelExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(user);
        //修改user的age值 方式一
        parser.parseExpression("age").setValue(context,55);
        //修改user的age值 方式二
        parser.parseExpression("age = 66").getValue(context);
    }
}
类型

T(全限定类名),如果在java.lang包下可以不写包名

public class test {
    public static void main(String[] args) {

        SpelExpressionParser parser = new SpelExpressionParser();
        //获得对应的class对象
        Class value = parser.parseExpression("T(String)").getValue(Class.class);
        Class value1 = parser.parseExpression("T(com.ke.spel.User)").getValue(Class.class);
        //可以直接调用静态方法
        String value2 = parser.parseExpression("T(com.ke.spel.User).say('你干嘛')").getValue(String.class);

    }
}
构造器

用new关键字,除了基本类型和String,其他都要用全限定类名

public class test {
    public static void main(String[] args) {

        SpelExpressionParser parser = new SpelExpressionParser();
        User value = parser.parseExpression("new com.ke.spel.User()").getValue(User.class);
        System.out.println(value);

    }
}
变量

在这里插入图片描述

public class test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("ck");
        user.setAge(18);
        EvaluationContext context = new StandardEvaluationContext(user);
        //把变量存在EvaluationContext(其中维护着一个map)对象中
        context.setVariable("newName","cxk");
        SpelExpressionParser parser = new SpelExpressionParser();
        parser.parseExpression("name=#newName").getValue(context);
        System.out.println(user.getName());
    }
}
集合过滤

在这里插入图片描述

public class test {
    public static void main(String[] args) {

        User user = new User();
        user.setName("ck");
        user.setAge(18);
        EvaluationContext context = new StandardEvaluationContext(user);
        //存入List
        ArrayList<Integer> integers = new ArrayList<>();
        integers.addAll(Arrays.asList(50,100,150,200,250,300,350));
        context.setVariable("list",integers);
        //存入Map
        HashMap map = new HashMap<>();
        map.put("ck",20);
        map.put("cyz",30);
        map.put("cxk",40);
        map.put("gs",50);
        context.setVariable("map",map);
        SpelExpressionParser parser = new SpelExpressionParser();
        //从list找出大于200的元素(this前有#号)
        ArrayList<Integer> value = (ArrayList<Integer>)parser.parseExpression("#list.?[#this>200]").getValue(context);
        //从map找value大于30的元素(value前没有#号)
        Map value1 = (Map)parser.parseExpression("#map.?[value>30]").getValue(context);
        //从map找value大于30的元素(value前没有#号)(^代表取出符合条件的第一个)
        Map value2 = (Map)parser.parseExpression("#map.^[value>30]").getValue(context);
        //从map找value大于30的元素(value前没有#号)($代表取出符合条件的最后一个)
        Map value3 = (Map)parser.parseExpression("#map.$[value>30]").getValue(context);
         //根据条件转换并返回对应 List(!符号)
        //[60, 70, 50, 80]
        ArrayList<Integer> value4 = (ArrayList<Integer>)parser.parseExpression("#map.![value+30]").getValue(context);
        //[250, 300, 350, 400, 450, 500, 550]
        ArrayList<Integer> value5 = (ArrayList<Integer>)parser.parseExpression("#list.![#this+200]").getValue(context);
        //[false, true, false, true]
        ArrayList<Integer> value6 = (ArrayList<Integer>)parser.parseExpression("#map.![value>30]").getValue(context);
        //[false, false, false, false, true, true, true]
        ArrayList<Integer> value7 = (ArrayList<Integer>)parser.parseExpression("#list.![#this>200]").getValue(context);


    }
}

Spring使用Spel表达式

基于XML配置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
       http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="hello" class="springEl.Mes"
          p:mes="#{systemProperties['java.class.path']}"
          p:mes1="#{systemProperties['os.name']}"
          p:mes2="#{ T(Double).toString(T(Math).random())}"
          p:mes3="#{ hello2.mes }"
    />

    <bean id="hello2" class="springEl.Mes"
          p:mes="你好"
    />

</beans>

systemProperties可以获得系统参数,也可以调用静态方法,也可以直接引用其他bean的值

public class test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beansEl.xml");
        Mes bean = (Mes)applicationContext.getBean("hello");
        //获取java环境变量
        System.out.println(bean.getMes());
        //获取操作系统版本 Windows 10
        System.out.println(bean.getMes1());
        //自定义设置的值0.5541974835747724
        System.out.println(bean.getMes2());
        //你好
        System.out.println(bean.getMes3());
    }
}

注解配置

配置文件peizhi.properties

username = ck
password = 666666
div = a.b.c.d

spring配置文件设置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    <!--扫描springEl包下的注解-->
    <context:component-scan base-package="springEl"/>
    <!--读取配置文件-->
    <util:properties id="properties" location="classpath:peizhi.properties"/>
    <!--配置可简写spel设置-->
    <context:property-placeholder properties-ref="properties"/>
</beans>

配置直接写入数据

@Component
@Data
public class config {
    @Value("#{properties['username']}")
    private String userName;
    @Value("#{properties['password']}")
    private String passWord;
    @Value("${div}")
    private String div;
}

在配置了spel简写后可以用${字段名}来简化

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值