avatar

目录
Spring表达式SpEL

本文只是SpEL的简单学习笔记,详细的内容请参考http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html

Spring表达式SpEL是一种表达式语言规范,最早用于Spring WebFlow中,大部分语法基于Unified Expression Language,这种语言在JSP和JSF中有广泛使用。

许多其他基于Spring的框架都可以通过插件或扩展的形式支持SpEL。

为成员或方法参数赋值

@Value中SpEL既可以直接设置某个成员的值,也可以用来设置某个@Bean方法的参数值。

java
1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
class TaxConfig {
@Value("#{ systemProperties['user.region'] }") String region;
@Bean
public TaxCalculator taxCalculator1() {
return new TaxCalculator( region );
}
@Bean
public TaxCalculator taxCalculator2
(@Value("#{ systemProperties['user.region'] }") String region, …) {
return new TaxCalculator( region );
}

使用SpEL获取信息

配合@Value注解,SpEL可以获取多种不同来源的信息。

访问Spring Bean

在Configuration类中,SpEL可以访问其他Bean中的资源。

java
1
2
3
4
class StrategyBean {
private KeyGenerator gen = new KeyGenerator.getInstance("Blowfish");
public KeyGenerator getKeyGenerator() { return gen; }
}
java
1
2
3
4
5
6
7
@Configuration
class StrategyConfig
{
@Bean public StrategyBean strategyBean() {
return new StrategyBean();
}
}

有如上定义之后,我们可以使用@Value注解配合SpEL访问到StrategyBean中提供的keyGenerator:

java
1
2
3
4
5
6
7
@Configuration
@Import(StrategyConfig.class)
class AnotherConfig
{
@Value("#{strategyBean.keyGenerator}") KeyGenerator kgen;

}

注意:SpEL表达式中,strategyBean会由IoC容器通过StrategyConfig中的配置注入,keyGenerator会使用StrategyBean中对应的get方法获得,这些对象和方法的名字使用默认的驼峰命名法命名即可被Spring框架正确识别。

访问Environment中的属性

有两种等价的写法,都可以访问Environment中的属性值:

  • @Value("${daily.limit}")
  • @Value("#{environment['daily.limit']}")

通过这种方法得到的值都是字符串,如果需要使用SpEL进行其他计算,可能需要类型转换,如:

  • @Value("#{new Integer(environment['daily.limit']) * 2}")
  • @Value("#{new java.net.URL(environment['home.page']).host}")

使用?:运算符提供fallback默认值

?:是SpEL中的运算符,与其他语言中三元运算符不同,SpEL中的?:可以简化为一个二元运算符,x?:y表示当x的值不为null时,表达式返回x的值,否则返回y值,我们可以使用这种写法为表达式提供默认值,避免一些运行时错误。

?:在左运算符是简单表达式时,可简写做:,下面的两种写法是等价的:

java
1
2
3
4
@Autowired
public TransferServiceImpl(@Value("${daily.limit : 100000}") int max) {
this.maxTransfersPerDay = max;
}
java
1
2
3
4
@Autowired
public setLimit(@Value("#{environment['daily.limit'] ?: 100000}") int max) {
this.maxTransfersPerDay = max;
}

表达式变量

对于SpEL来说,表达式变量可以是:

  • Spring Bean,比如前面例子中的strategyBean
  • 其他隐式引用:一些引用可以默认可以在SpEL中直接使用,比如Environment和系统变量,另一些可能需要配合应用上下文使用

SpEL也允许开发者自定义函数和引用,在很多以Spring为基础的框架中都有这样的用法,比如Spring Security等,可以参考相关文档。

打赏
  • 微信
    微信
  • 支付宝
    支付宝