使用SpEL自留记录

使用SpEL初体验-自留记录

使用实例

要使用spel解析器,包基本都在org.springframework.expression里,基础依赖里边就包含,我是在项目中需要做动态前置校验,使用该方案,下边是我项目中使用情景
在这里插入图片描述
忽略报错,只是为了拍照放到一起了。

  1. EvaluationContext context = new tandardEvaluationContext(ctxObj);中参数为JSONObject对象,这句话是构建上下文,为之后执行表达式进行数据准备
  2. parser.parseExpression(String.class) 中的参数 是表达式,原本使用为 “name != null”,但是会报错 property of type ‘name’ cannot be found on object of type ‘com.alibaba.fastjson’ - maybe not public or not valid 报错解决下边再提
  3. exp.getValue(context, Boolean.class);获取解析结果,我需要的是boolean类型,所以用Boolean.class,若是表达式返回其他类型,可依据需要修改,例如exp.getValue(context, String.class)

到这里就算是解析完了,原理大概是依据上下文的数据,代入规定的表达式中执行,然后返回结果,但是其中遇到另外问题,我只用最简单的举例,正常来说上下文中只要是map格式,解析器是可以直接依据key获取到值的,但是在使用过程中,并未获取到(也就是第二条中的问题),于是在网上进行了搜索,需要自定义属性访问器来解决

public class JSONObjectPropertyAccessor implements PropertyAccessor {
    @Override
    public Class<?>[] getSpecificTargetClasses() {
        return new Class<?>[]{JSONObject.class};
    }

    @Override
    public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
     //可读规范定义 仅读取JSONObject格式数据,且需要在target中-就是上下文中对象里得有这个key
        return target instanceof JSONObject && ((JSONObject) target).containsKey(name);
    }

    @Override
    public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
    // 读取逻辑
        JSONObject jsonObject = (JSONObject) target;
        return new TypedValue(jsonObject.get(name));
    }

    @Override
    public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
    // 可写规范定义   均可写
        return true;
    }

    @Override
    public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
    // 写入逻辑
        JSONObject jsonObject = (JSONObject) target;
        jsonObject.put(name, newValue);
    }
}

自定义属性访问需要实现PropertyAccessor接口,并实现其中的方法,如canRead、read、canWrite和write;
使用自定义属性访问器

StandardEvaluationContext context = new StandardEvaluationContext(ctxObj);
context.addPropertyAccessor(new MyPropertyAccessor());

总结

其实spel很多地方都在用

  1. 配置文件中的使用
    在 Spring 配置文件中,可以使用 SpEL 来动态地设置 Bean 的属性。例如:
<bean id="myBean" class="com.example.MyBean">
    <property name="name" value="#{systemProperties['user.name']}"/>
    <property name="age" value="#{10 + 20}"/>
</bean>

这里,#{systemProperties[‘user.name’]} 动态地从系统属性中获取用户名,#{10 + 20} 计算两个数字的和。

  1. 在注解中使用
    Spring 还支持在注解中使用 SpEL,例如在 @Value 注解中:
@Component
public class MyComponent {
    @Value("#{systemProperties['user.home']}")
    private String userHome;
 
    @Value("#{T(java.lang.Math).random() * 100.0}")
    private double randomNumber;
}
  1. 条件表达式
    SpEL 可以用来编写条件表达式,例如在 @Conditional 注解中:
@Configuration
public class AppConfig {
    @Bean
    @Conditional(#{systemProperties['my.condition'] == 'true' ? MyCondition.class : NoOpCondition.class})
    public MyBean myBean() {
        return new MyBean();
    }
}
  1. 方法调用与引用
    SpEL 支持直接调用 Java 方法,并引用其他 Bean:
@Component
public class MyComponent {
    @Value("#{myService.getSomeData()}")
    private String data;
}
  1. 集合操作
    SpEL 可以用来处理集合,例如筛选、投影等:
@Value("#{ {'a', 'b', 'c'} ? [el | el.toUpperCase()] }")
private List<String> upperCaseLetters; // 结果: ['A', 'B', 'C']
  1. 访问和修改 Bean 的属性
    在运行时,可以通过 SpEL 来访问和修改 Bean 的属性:
@Autowired
private MyBean myBean;
 
public void updateBean() {
    ExpressionParser parser = new SpelExpressionParser();
    EvaluationContext context = new StandardEvaluationContext(myBean);
    parser.parseExpression("name").setValue(context, "New Name"); // 修改 name 属性值
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值