返回顶部
首页 > 资讯 > 后端开发 > Python >SpringBoot SpringEL表达式的使用
  • 859
分享到

SpringBoot SpringEL表达式的使用

2024-04-02 19:04:59 859人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、springEL-基础介绍二、EL表达式-基础使用三、SpringEL-基础使用四、属性自动注入一、SpringEL-基础介绍 什么是SpringEL(SpEL)?

一、SpringEL-基础介绍

什么是SpringEL(SpEL)?

  • Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式
  • SpringEL可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中
  • SpringEL可以调用jdk中提供的静态常量,获取外部Properties文件中的的配置

为什么要使用SpringEL?

  • 平常通过配置文件或Annotaton注入的Bean,其实都可以称为静态性注入
  • 如Bean A中有变量A,它的值需要根据Bean B的B变量为参考,在这场景下静态注入就对这样的处理显得非常无力
  • 而Spring3增加的SpringEL就可以完全满足这种需求,而且还可以对不同Bean的字段进行计算再进行赋值,功能非常强大

如何使用SpringEL?

  • SpringEL从名字来看就能看出和EL是有点关系的,SpringEL的使用和EL表达式的使用非常相似
  • EL表达式在jsP页面更方便的获取后台中的值,而SpringEL就是为了更方便获取Spring容器中的Bean的值
  • EL使用${},而SpringEL使用#{}进行表达式的声明

两者主要区别

  • $是去找外部配置的参数,将值赋过来
  • #是SpEL表达式,去寻找对应变量的内容
  • 也可以直接使用@value("常量")注入不使用EL,这样写法与直接赋值等价

如果是在Spring中使用可以使用**@PropertySource("classpath:my.properties")**加载对应配置文件

二、EL表达式-基础使用


# 配置文件
com:
  codecoord:
    el:
      num: 1001
      name: el
      language:
        - java
        - spring
        - Mysql
        - linux
      # 逗号分隔可以注入列表
      language02: java,spring,mysql,linux

使用EL注入简单值



@Value("1432516744")
private Integer no;

注入配置文件属性值



@Value("${com.codecoord.el.num}")
private Integer num;

@Value("${com.codecoord.el.name}")
private String name;

注入默认值



@Value("${com.codecoord.el.skill:java}")
private String skill;

注入列表

  • 不支持直接配置文件中数组语法格式注入列表
  • 可以识别使用逗号,分隔的配置,spring默认以,分隔

// 错误写法:不支持直接注入yml列表格式语法列表
@Value("${com.codecoord.el.language}")
private List<String> listLanguage;
@Value("${com.codecoord.el.language}")
private String[] strLanguage;


@Value("${com.codecoord.el.language02}")
private List<String> listLanguage02;
@Value("${com.codecoord.el.language02}")
private String[] strLanguage02;

完整参考如下

配置文件


server:
  port: 8888
com:
  codecoord:
    el:
      num: 1001
      name: el
      language:
        - java
        - spring
        - mysql
        - linux
      # 逗号分隔可以注入列表
      language02: java,spring,mysql,linux

属性配置类


import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;

@Data
@Component
public class ElConfig {
    
    @Value("1432516744")
    private Integer no;
    
    @Value("${com.codecoord.el.num}")
    private Integer num;
    
    @Value("${com.codecoord.el.name}")
    private String name;
    
    @Value("${com.codecoord.el.skill:java}")
    private String skill;
    /// 不支持直接注入列表
    
    
    @Value("${com.codecoord.el.language02}")
    private List<String> listLanguage02;
    @Value("${com.codecoord.el.language02}")
    private String[] strLanguage02;
}

向controller中注入配置类,然后访问接口测试结果如下


{
 "no": 1432516744,
 "num": 1001,
 "name": "el",
 "skill": "java",
 "listLanguage02": [
  "java",
  "spring",
  "mysql",
  "linux"
 ],
 "strLanguage02": [
  "java",
  "spring",
  "mysql",
  "linux"
 ]
}

三、SpringEL-基础使用

1、使用SpEL注入简单值和普通EL注入使用基本一致
2、SpEl注入map

  • 配置文件中需要使用双引号括起来,否则将会注入失败,key为单引号

# SpEl
spEl:
  mapinject: "{'name': 'SpEl', 'WEBsite': 'Http://www.codeocord.com'}"

java类中先使用${spEl.mapInject}注入字符串值,#{}会解析字符串的值转为map


@Value("#{${spEl.mapInject}}")
private Map<String, String> mapInject;

3、SpEl注入list

  • 除了可以通过EL注入listI外,也可以使用#{${}.split('分隔符')}的方式注入List
  • 配置文件中例如使用#分隔

spEl:
  listInject: "44#11#99#100"

java类中先使用${spEl.listInject}注入字符串值,内容使用单引号括起来,然后对字符串使用split方法分隔
提示:避免为空情况,可以给一个默认值空串


@Value("#{'${spEl.listInject:}'.split('#')}")
 private List<String> listInject;

4、动态注入

上述注入都是静态注入,SpEl支持从Spring容器中注入信息,称为动态注入。动态注入类如下 


import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Data
public class SpElConstant {
    private String name = "SpElConstant-name";
    private String nickname = "tianxin";
    private int num = 100;
    private List<String> product = new ArrayList<String>() {{
        add("huaweiMate30Pro");
        add("xiaomi10x5g");
    }};
    private Map<String, String> productMap = new HashMap<String, String>() {{
        put("huaweiMate30Pro", "5999");
        put("xiaomi10x5g", "4999");
    }};
    private List<City> cityList = new ArrayList<City>() {{
        add(new City("深圳", 1000L));
        add(new City("杭州", 2000L));
        add(new City("贵阳", 900L));
    }};

    public String showProperty() {
        return "showProperty-无参数";
    }

    public String showProperty(String name) {
        return "showProperty-" + name;
    }

    @Data
    @AllArgsConstructor
    static class City {
        private String name;
        private long population;
    }
}

SpEl支持和不支持操作

  • 支持动态注入实例,类似于对象自动注入
  • SPL不支持直接注入配置文件中的配置
  • 支持调用静态和实例方法
    • 静态方法:@Value("#{T(package.ClassName).ConstFieldName")
  • 支持调用静态类或常量
  • 支持运算符运算
  • 支持操作集合
  • 支持查询筛选集合和投影

注入完整操作如下


import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Data
@Component
public class SpElConfig {
    /// 不支持直接注入配置文件值
    
    
    @Value("#{spElConstant}")
    private SpElConstant spElConstant;
    
    @Value("#{spElConstant.name}")
    private String name;
    
    @Value("#{spElConstant.showProperty()}")
    private String method1;
    
    @Value("#{spElConstant.showProperty('Hell SpringEL')}")
    private String method2;
    
    @Value("#{spElConstant.showProperty().toUpperCase()}")
    private String method3;
    
    @Value("#{spElConstant.showProperty()?.toUpperCase()}")
    private String method4;
    
    @Value("#{T(java.lang.Math).PI}")
    private double pi;
    
    @Value("#{T(java.lang.Math).random()}")
    private double random;
    
    @Value("#{T(java.io.File).separator}")
    private String separator;
    
    @Value("#{spElConstant.nickname + ' ' + spElConstant.name}")
    private String concatString;
    
    @Value("#{3 * T(java.lang.Math).PI + spElConstant.num}")
    private double operation;
    
    @Value("#{spElConstant.num > 100 and spElConstant.num <= 200}")
    private boolean logicOperation;
    
    @Value("#{not (spElConstant.num == 100) or spElConstant.num <= 200}")
    private boolean logicOperation2;
    
    @Value("#{spElConstant.num > 100 ? spElConstant.num : spElConstant.num + 100}")
    private Integer logicOperation3;
    
    @Value("#{spElConstant.product[0]}")
    private String str;
    
    @Value("#{spElConstant.product[0]?.toUpperCase()}")
    private String upperStr;
    
    @Value("#{spElConstant.productMap['hello']}")
    private String mapValue;
    
    @Value("#{spElConstant.productMap[spElConstant.product[0]]}")
    private String mapStrByproduct;
    
    @Value("#{spElConstant.cityList.?[population >= 1000]}")
    private List<SpElConstant.City> cityList;
    
    @Value("#{spElConstant.cityList.?[population == 900]}")
    private SpElConstant.City city;
    
    @Value("#{spElConstant.cityList.?[population >= 1000].![name]}")
    private List<String> cityName;
}

注入结果


{
 "spElConstant": {
  "name": "SpElConstant-name",
  "nickname": "tianxin",
  "num": 100,
  "product": [
   "huaweiMate30Pro",
   "xiaomi10x5g"
  ],
  "productMap": {
   "xiaomi10x5g": "4999",
   "huaweiMate30Pro": "5999"
  },
  "cityList": [
   {
    "name": "深圳",
    "population": 1000
   },
   {
    "name": "杭州",
    "population": 2000
   },
   {
    "name": "贵阳",
    "population": 900
   }
  ]
 },
 "name": "SpElConstant-name",
 "method1": "showProperty-无参数",
 "method2": "showProperty-Hell SpringEL",
 "method3": "SHOWPROPERTY-无参数",
 "method4": "SHOWPROPERTY-无参数",
 "pi": 3.141592653589793,
 "random": 0.19997238292235787,
 "separator": "\\",
 "concatString": "tianxin SpElConstant-name",
 "operation": 109.42477796076938,
 "logicOperation": false,
 "logicOperation2": true,
 "logicOperation3": 200,
 "str": "huaweiMate30Pro",
 "upperStr": "HUAWEIMATE30PRO",
 "mapValue": null,
 "mapStrByproduct": "5999",
 "cityList": [
  {
   "name": "深圳",
   "population": 1000
  },
  {
   "name": "杭州",
   "population": 2000
  }
 ],
 "city": {
  "name": "贵阳",
  "population": 900
 },
 "cityName": [
  "深圳",
  "杭州"
 ]
}

Spring操作外部Properties文件


<!-- 首先通过applicaContext.xml中<util:properties>增加properties文件 -->
<!-- 注意需要引入Spring的util schemea命名空间和注意id属性,id属性将在SpringEL中使用 -->
<util:properties id="db" location="classpath:application.properties"/>


public class TestSpringEL {
 // 注意db为xml文件中声明的id
 @Value("#{db['jdbc.url']}")
 private String propertiesValue;
}

SpringEL在使用时仅仅是一个字符串,不易于排错与测试,也没有IDE检查我们的语法,当出现错误时较难检测,复杂的表达式不建议通过SpringEL方式注入。在非必要情况下,不推荐使用SpEl的复杂注入,清晰可读的代码更为重要且有利于排查问题

四、属性自动注入

上述都是通过指定字段进行注入,可以通过@ConfigurationProperties指定前缀进行自动注入


org.springframework.boot.context.properties.ConfigurationProperties

配置类


user:
  id: ${random.uuid}
  name: autowire
  address: unknown
  website: www.codecoord.com
  age: ${random.int}

自动属性注入类

  • 通过prefix指定前端为user,然后将会把user.后的类型按照名称进行注入
  • 注意必须要提供setter方法

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "user")
@Data
public class UserConfig {
    private String id;
    private String name;
    private String address;
    private String website;
    private Integer age;
}

可以通过@EnableConfigurationProperties(value = UserConfig.class)将UserConfig再次强制注入,问题出现在如果UserConfig为第三方jar包内的配置类,则可能出现属性没有注入情况,所以可以指定注入

到此这篇关于SpringBoot SpringEL表达式的使用的文章就介绍到这了,更多相关SpringEL表达式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: SpringBoot SpringEL表达式的使用

本文链接: https://lsjlt.com/news/131072.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringBoot SpringEL表达式的使用
    目录一、SpringEL-基础介绍二、EL表达式-基础使用三、SpringEL-基础使用四、属性自动注入一、SpringEL-基础介绍 什么是SpringEL(SpEL)? ...
    99+
    2024-04-02
  • 基于springEL表达式详解及应用
    目录基于springEL表达式详解及应用什么是SpringEL?为什么要使用SpringEL?如何使用SpringEL?使用SpringEL注入简单值使用SpringEL调用方法Sp...
    99+
    2024-04-02
  • 【javaSE】 Lambda表达式与Lambda表达式的使用
    文章目录 🌳Lambda表达式的背景🚩Lambda表达式的语法🚩函数式接口 🎋Lambda表达式的基本使用🎄...
    99+
    2023-09-15
    开发语言 java Lambda表达式 源码
  • 使用Springboot自定义注解,支持SPEL表达式
    目录Springboot自定义注解,支持SPEL表达式1.自定义注解2.使用AOP拦截方法,解析注解参数自定义注解结合切面和spel表达式自定义一个注解自定义一个service类,在...
    99+
    2024-04-02
  • SQLCASE表达式的具体使用
    目录CASE 表达式里的聚合函数聚合与非聚合不能混用WHERE 中的 CASEGROUP BY 中的 CASEORDER BY 中的 CASE总结CASE 表达式分为简单表达...
    99+
    2024-04-02
  • QueryWrapper的lambda表达式使用OR
    com.baomidou.mybatisplus.core.conditions.query.QueryWrapper是MybatisPlus框架构造查询条件常用的对象 使用lambda表达式写法更为清晰,简洁: QueryWrap...
    99+
    2023-08-31
    java mybatis Powered by 金山文档
  • bashshell逻辑表达式的使用
    目录前言test数字比较字符串比较文件比较、类型/属性检查逻辑与:-a,逻辑或:-o[命令[[ expression ]]前言 控制语句需要逻辑表达式进行分支判断,bash shel...
    99+
    2023-05-19
    shell逻辑表达式
  • python 正则表达式的使用
    目录1、正则表达式 1.1 正则表达式字符串1.1.1 元字符1.1.2 字符转义1.1.3 开始与结束字符1.2 字符类1.2.1 定义字符类1.2.2 字符串取反1.2.3 区间...
    99+
    2024-04-02
  • jmeter正则表达式的使用
    运用Jmeter正则提取器,可以从请求的响应结果中取到需要的内容,从而实现关联。 关联是请求与请求之间存在数据依赖关系,需要从上一个请求获取下一个请求需要回传回去的数据 在查看结果...
    99+
    2024-04-02
  • MariaDB表表达式之公用表表达式(CTE)
    目录前言1.非递归CTE2.递归CTE2.1 语法2.2 递归CTE示例(1)2.2 递归CTE示例(2)2.2 递归CTE示例(3)总结前言 公用表表达式(Common Table...
    99+
    2024-04-02
  • SQL 中 CASE 表达式的使用方式
    目录1. 前言2. 语法3. 注意点4. 分类汇总数据5. 一条SQL实现不同条件的统计6. 使用CHECK约束定义多个列的条件关系7. 在UPDATE语句中进行条件分支8. 生成交叉表9. CASE表达式中使用...
    99+
    2024-04-02
  • SQL中CASE表达式的使用方式
    目录1. 前言2. 语法3. 注意点4. 分类汇总数据5. 一条SQL实现不同条件的统计6. 使用CHECK约束定义多个列的条件关系7. 在UPDATE语句中进行条件分支8....
    99+
    2024-04-02
  • C#使用正则表达式
    一.正则基础 1. []方括号表示匹配可以匹配方括号中的任意点单个字符,方括号只允许匹配单个字符。2. | 或表示两项之间的一个选择,它不能和方括号使用,只能和小括号使用。3. ()...
    99+
    2024-04-02
  • Quartz表达式怎么使用
    Quartz表达式是一种时间表达式语言,用于配置Quartz调度器的任务调度时间。其基本语法为:[秒] [分钟] [小时] [日] ...
    99+
    2023-09-26
    Quartz
  • lambda表达式使用方法
    本篇内容介绍了“lambda表达式使用方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!package test;import java.u...
    99+
    2023-06-02
  • SQL正则表达式及mybatis中使用正则表达式的方法
    小编给大家分享一下SQL正则表达式及mybatis中使用正则表达式的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!mysql...
    99+
    2024-04-02
  • java Lambda表达式的使用心得
    目录Lambda表达式的心得Lambda表达式法传统方法使用Lambda表达式 你首先要知道的Lambda表达式的技巧Lambda表达式只能用来简化仅包含一个public方法的接口的...
    99+
    2024-04-02
  • C#运算符表达式的使用
    这篇文章主要介绍“C#运算符表达式的使用”,在日常操作中,相信很多人在C#运算符表达式的使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#运算符表达式的使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-18
  • bash shell逻辑表达式的使用
    目录前言test数字比较字符串比较文件比较、类型/属性检查逻辑与:-a,逻辑或:-o[命令[[ expression ]]前言 控制语句需要逻辑表达式进行分支判断,bash shell逻辑表达式一般有3种写法:test ...
    99+
    2023-05-12
    shell逻辑表达式
  • python 中正则表达式的使用
    正则表达式(re)(Regular Expression)。正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。在pyth...
    99+
    2023-01-31
    正则表达式 python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作