Spel快速入门及查找手册

Spel快速查找手册

此博文为Spel速查手册,用来快速查找平时开发中会出现的Spel。如果需要更详细的代码示例,可在示例代码中找到

基础知识

@Value的两种格式

在Springboot中,@Value有两种写法

  1. ${}写法,取Springboot属性文件application*.yml中的属性值

    @Value("${jack.sparrow.name}")
    private Strinh
    
  2. #{}写法,里面是spel表达式

    @Value("#{spelEntity.name}")
    private String name;
    

Spel Context的作用

像其他容器一样,负责Spel的解析

大致了解了上述这两个基础知识外,就可以进行Spel的学习了

取值

因为平时开发中使用取值的场景较多,所以,先说Spel取值。可以思考一下平时一个Java对象里放的都有哪些属性,然后根据这些属性,思考如何取值,进行针对性学习,可以快速入门Spel。

示例Java对象

如上所述,建立一个Java对象。平时开发中,里面放的最多的也就是包装类型、集合类型、其他Java对象。大体上就这么三类

@Getter
@Setter
@ToString
public class SpelEntity {

    private Integer age = new Integer(2021);

    private String name = "jacksparrow";

    private Boolean child;

    private List<String> list;

    private Map<Integer, Integer> map;

    private SpelAnotherEntity anotherEntity;

    private List<SpelAnotherEntity> objectList;

    private Map<String, SpelAnotherEntity> objectMap;
    
    /**
     * 实例方法.
     */
    public Date myDate() {
        return Calendar.getInstance().getTime();
    }
}

@Getter,@Setter,@ToString均属于Lombok注解,有兴趣可以了解,这里不做过多介绍。

自己可以new一个该对象,并给属性设置一些示例值。这里使用ExpressionParser来进行Spel的解析

ExpressionParser parser = new SpelExpressionParser();

获取对象中属性

log.info("获取name属性的值为{}", parser.parseExpression("name").getValue(spelEntity));
log.info("获取age属性的值为{}", parser.parseExpression("age").getValue(spelEntity));
log.info("获取child属性的值为{}", parser.parseExpression("child").getValue(spelEntity));

获取集合里的对象

// 访问集合时,list直接通过index访问,map直接通过【key】访问,如果key是字符串,则通过【'key'】访问
log.info("获取list第一项的值为{}", parser.parseExpression("list[0]").getValue(spelEntity));
log.info("获取map属性中key为1的值为{}", parser.parseExpression("map[1]").getValue(spelEntity));

获取集合里对象的属性

// 获取对象List的属性时,和正常一样list[index]获取到的是里面对象,访问对象的属性通过【.属性】
log.info("访问对象List集合的属性{}", parser.parseExpression("objectList[0].date").getValue(spelEntity));
// 获取对象map中的value为对象时,访问具体属性,依旧通过【.属性】访问
log.info("访问对象Map集合的属性{}", parser.parseExpression("objectMap['objectKey'].date").getValue(spelEntity));

获取对象

通过Spel表达式获取对象,并返回该对象

// 获取属性或对象时,在getValue中需【设置返回的类型】是什么
SpelAnotherEntity spelAnotherEntity = parser.parseExpression("anotherEntity").getValue(spelEntity, SpelAnotherEntity.class);
log.info("获取spelEntity中的对象属性{}", spelAnotherEntity);
// 获取对象Map属性时,返回类型设置为Map,用具体的Map<K, V>接收即可
Map<String, SpelAnotherEntity> objectMap1 = parser.parseExpression("objectMap").getValue(spelEntity, Map.class);

获取对象并调用方法

log.info("调用toUpperCase方法值为{}", parser.parseExpression("list[0].toUpperCase()").getValue(spelEntity));

调用某些不是JDK自带的,比如是我们自己写的方法,拿构造方法举例

SpelAnotherEntity value1 = parser.parseExpression("new com.learn.spring.springuse.advanced.spel.SpelAnotherEntity()").getValue(spelEntity, SpelAnotherEntity.class);

调用工具类的静态方法

格式为T(类的完全限定名).方法(参数)

log.info("调用静态方法的方法值为{}", parser.parseExpression("T(org.springframework.util.StringUtils).capitalize(list[1])").getValue(spelEntity));

不经常用,可以了解

以下这些属于平时开发中不太常用的,但是可以了解一下,毕竟知道了也没坏处不是

集合判空

访问集合中的元素,或者集合中元素的属性,一旦该元素不存在,那么访问其属性会报NPE。如何处理这种情况呢?

// 访问集合属性时元素不存在或者index过大应该怎么防止报错?使用三目运算,假设我要访问第4个元素,判断list的size是否小于4,如果小于4则返回null
log.info("访问集合时判断是否超过集合值为{}", parser.parseExpression("list.size() < 4 ? null:list[3]").getValue(spelEntity));

log.info("获取map中不存在的对象的属性防止NPE(Null Pointer Exception)异常{}", parser.parseExpression("objectMap['objectKeys']?.date").getValue(spelEntity));
集合过滤

list过滤

// 按照过滤条件找出集合中符合条件的元素,过滤之后返回的是集合,如果在list中过滤,则返回list,在map中过滤,返回map
// 使用格式     ?.[条件]
// 这里使用#this,表示当前对象
List<String> filterList = (List<String>) parser.parseExpression("list.?[#this =='china']").getValue(spelEntity);
log.info("list集合过滤后的值为{}", filterList.get(0));


// 对于集合过滤之后会返回满足条件的所有元素,如何返回第一个、最后一个匹配的元素
// 返回第一个 .^[条件]
// 返回最后一个 .$[条件]
log.info("获取list中匹配的第一个值{}", parser.parseExpression("list.^[#this == 'china']").getValue(spelEntity));
log.info("获取list中匹配的第一个值{}", parser.parseExpression("list.$[#this == 'china']").getValue(spelEntity));

map过滤

Map<Integer, Integer> filterKeyMap = (Map<Integer, Integer>) parser.parseExpression("map.?[key == 1]").getValue(spelEntity);
        Map<Integer, Integer> filterValueMap = (Map<Integer, Integer>) parser.parseExpression("map.?[value == 100]").getValue(spelEntity);
log.info("map集合Key过滤后的值为{}", filterKeyMap);
log.info("map集合Value过滤后的值为{}", filterValueMap);

设值

基础类型以及包装类

对于这些类型,平时开发中直接在@Value("#{spel表达式}")中设置对应的值即可

@Value("#{1}")
private Integer code;

@Value("#{'initString'}")
private String initStr;

@Value("#{true}")
private Boolean initBool;

集合设值

集合设值使用=={}==表示集合,集合类型为list,则直接在{}写元素值即可;集合类型为Map,则在{}以key:value的形式写即可。集合各个元素之间用逗号分隔。

@Value("#{ {'jack', 'jan'} }")
private List<String> integerList;

@Value("#{ {1, 2,3} }")
private List<Integer> stringList;

@Value("#{ {'china':1, 'usa':2, 'japan':3} }")
private Map<String, Integer> map;

在属性上调用方法

可取值那里一样,这里简单给个例子

// 为当前对象中的对象属性赋值,通过调用其构造方法
@Value("#{ new com.learn.spring.springuse.advanced.spel.SpelEntity() }")
private SpelEntity spelEntity;

// 调用静态方法
@Value("#{ T(com.google.common.collect.Lists).newArrayList() }")
private List<Integer> initListByGuava;

备注

示例代码

文档

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值