Spring EL表达式


目录:

  1. 简介

  2. 常见使用方式

    2.1 注入简单值

    2.2 调用方法

    2.3 调用静态类或常量

    2.4 运算

    2.5 操作集合

    2.6 操作外部Properties文件

    2.7 查询筛选集合和投影

  3. Spring Security使用Spring EL

参考/来源:

简介

  • 什么是SpringEL?

    Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中,更可以调用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使用#{}进行表达式的声明。

常见使用方式

注入简单值

public class TestSpringEL {
	
	/*
	 * @Value注解等同于XML配置中的<property/>标签, 
	 * SpringEL同样支持在XML<property/>中编写
	*/
	
	// 注入简单值,输出num为5
	@Value("#{5}")
	
	private Integer num;
	
	// 注入ID为testConstant的Bean
	@Value("#{testConstant}")
	
	private TestConstant Constant;
	
	// 注入ID为testConstant Bean中的STR常量/变量
	@Value("#{testConstant.STR}")
	private String str;

}

调用方法

public class TestSpringEL {
	
	/*
	 * TestConstant类中有两个方法重载,
	 * 返回值为String类型
	*/
	
	// 调用无参方法
	@Value("#{testConstant.showProperty}")
	private String method1;
	
	// 有参接收字符串的方法
	@Value("#{testConstant.showProperty('Hello')}")
	private String method2;
	
	/*
	 * 若然希望方法返回的String为大写
	*/
	@Value("#{testConstant.showProperty().toUpperCase()}")
	private String method3;
	
	/*
	 * 若使用method3这种方式,若然showProperty返回为null, 
	 * 将会抛出NullPointerException,可以使用以下方式避免
	*/
	@Value("#{testConstant.showProperty()?.toUpperCase}")
	private String method4;
	
	/*
	 * 使用?.符号代表若然左边的值为null,将不执行右边方法, 
	 * 读者可以灵活运用在其他场景,只要左边可能返回null,
	 * 即可使用上面示例中的?.
	*/
}

调用静态类或常量

public class TestSpringEL {

	/*
	 * 注入JDK中的工具类常量或调用工具类的方法
	*/
	
	// 获取Math的PI常量
	@Value("#{T(java.lang.Math).PI")
	private double pi;
	
	// 调用random方法获取返回值
	@Value("#{T(java.lang.Math).random()}")
	private double ramdom;
	
	// 获取文件路径符号
	@Value("#{T(java.io.File).separator}")
	private String separator;
}

运算

public class TestSpringEL {

	/*
	 * 使用SpringEL进行运算及逻辑操作
	*/
	
	// 拼接字符串
	@Value("#{testConstant.nickname + ' ' + testConstant.name}")
	private String concatString;
	
	// 对数字类型进行运算,testConstant拥有num属性
	@Value("#{ 3 * T(java.lang.Math).PI + testConstant.num}")
	private double operation;
	
	// 进行逻辑运算
	@Value("#{testConstant.num > 100 and testConstant.num <= 200}")
	private boolean logicOperation;
	
	// 进行或非逻辑操作
	@Value("#{ not testConstant.num == 100 or testConstant.num <= 200}")
	private boolean logicOperation2;
	
	// 使用三元运算符
	@Value("#{testConstant.num > 100 ? testConstant.num : testConstant.num + 100}")
	private Integer logicOperation3;
}

使用正则表达式

public class TestSpringEL {

	// 验证是否邮箱地址正则表达式
	@Value("#{testConstant.STR match '\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+'}")
	private boolean regularExpression;
}

操作集合

public class TestSpringEL {

	/*
	 * TestConstant类中拥有名为testList的List变量, 和名为testMap的Map
	*/
	
	// 获取下标为0的元素
	@Value("#{testConstant.testList[0]}")
	private String str;
	
	// 获取下标为0元素的大写形式
	@Value("#{testConstant.testList[0]?.toUpperCase()}")
	private String upperStr;
	
	// 获取map中key为hello的value
	@Value("#{testConstant.testMap['hello']}")
	private String mapValue;
	
	// 根据testList下标为0元素作为key获取testMap的value
	@Value("#{testConstant.testMap[testConstant.testList[0]]}")
	private String mapStrByTestList;
}

操作外部Properties文件

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

<util:properties id="test" location="classpath:application.properties"/>
public class TestSpringEL {

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

查询筛选集合和投影

public class TestSpringEL {

	/*
	 * 声明City类,有population属性 testContants拥有名叫cityList的City类List集合
	*/
	
	// 过滤testConstant中cityList集合population属性大于1000的全部数据注入到本属性
	@Value("#{testConstant.cityList.?[population > 1000]}")
	private List<City> cityList;
	
	// 过滤testConstant中cityList集合population属性等于1000的第一条数据注入到本属性
	@Value("#{testConstant.cityList.^[population == 1000]}")
	private City city;
	
	// 过滤testConstant中cityList集合population属性小于1000的最后一条数据注入到本属性
	@Value("#{testConstant.cityList.$[population < 1000]}")
	private City city2;
	
	/*
	 * 首先为city增加name属性,代表城市的名称
	*/
	
	/*
	 * 假如我们在过滤城市集合后只想保留城市的名称,
	 * 可以使用如下方式进行投影
	*/
	@Value("#{testConstant.cityList.?[population > 1000].![name]}")
	private List<String> cityName;
}

Spring Security使用Spring EL

Spring Security允许我们在定义URL访问或方法访问所应有的权限时使用Spring EL表达式,在定义所需的访问权限时如果对应的表达式返回结果为true则表示拥有对应的权限,反之则无

Spring Security可用表达式对象的基类是SecurityExpressionRoot,其为我们提供了如下在使用Spring EL表达式对URL或方法进行权限控制时通用的内置表达式。

image-20220312170253284

文章作者: 小小千千
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小千千 !
评论
  目录